From d5c322030fbbcbc578fe5a3d6834f1f5587e65ce Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Tue, 2 May 2017 11:16:57 -0230 Subject: [PATCH 01/24] Adds initial version of DTrace supports. --- scripts/loom-fbsdmake | 2 +- src/CMakeLists.txt | 1 + src/DTraceLogger.cc | 68 +++++++++++++++++++++++++++++++++++++++++++ src/DTraceLogger.hh | 59 +++++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/DTraceLogger.cc create mode 100644 src/DTraceLogger.hh diff --git a/scripts/loom-fbsdmake b/scripts/loom-fbsdmake index 1e146fb..55f26f7 100755 --- a/scripts/loom-fbsdmake +++ b/scripts/loom-fbsdmake @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/sh -x . `dirname $0`/xtools.sh diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 236a2c5..6a50904 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,6 @@ set(FILES DebugInfo + DTraceLogger Instrumentation Instrumenter InstrStrategy diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc new file mode 100644 index 0000000..92284a9 --- /dev/null +++ b/src/DTraceLogger.cc @@ -0,0 +1,68 @@ +//! @file DTraceLogger.cc Definition of @ref DTraceLogger. +/* + * Copyright (c) 2017 Brian Kidney + * All rights reserved. + * + * This software was developed by BAE Systems, the University of Cambridge + * Computer Laboratory, and Memorial University under DARPA/AFRL contract + * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing + * (TC) research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 "DTraceLogger.hh" + +#include +#include + +using namespace loom; +using namespace llvm; +using std::vector; + +DTraceLogger::DTraceLogger(llvm::Module& Mod) + : Logger(Mod){}; + +Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, + StringRef Name, StringRef Descrip, + bool /* SuppressUniqueness */) { + + + IRBuilder<> B(I); + + LLVMContext &Ctx = Mod.getContext(); + std::vector params = { TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx)}; + auto *FT = FunctionType::get( TypeBuilder::get(Ctx), params, false); + + Constant *F = Mod.getOrInsertFunction("dt_probe", FT); + + ArrayRef args( Mod.getNamedValue(Name) ); + + return B.CreateCall(F, args); + +} + diff --git a/src/DTraceLogger.hh b/src/DTraceLogger.hh new file mode 100644 index 0000000..0bcb04e --- /dev/null +++ b/src/DTraceLogger.hh @@ -0,0 +1,59 @@ +//! @file DTraceLogger.hh Declaration of @ref DTraceLogger. +/* + * Copyright (c) 2017 Brian Kidney + * All rights reserved. + * + * This software was developed by BAE Systems, the University of Cambridge + * Computer Laboratory, and Memorial University under DARPA/AFRL contract + * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing + * (TC) research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 DTRACE_LOGGER_H_ +#define DTRACE_LOGGER_H_ + +#include "Logger.hh" + +namespace loom { + +class Serializer; + +/** + * A logging technique that writes values to the DTrace framework using + * Userland Statically Defined Traces (USDT). libusdt is used to create probes + * at runtime. + */ +class DTraceLogger : public loom::Logger { +public: + DTraceLogger(llvm::Module& Mod); + + + virtual llvm::Value* Log(llvm::Instruction *I, llvm::ArrayRef Values, + llvm::StringRef Name, llvm::StringRef Descrip, + bool /* SuppressUniqueness */) override; +}; + +} // namespace loom + +#endif // !DTRACE_LOGGER_H_ From 484121f5df3f3b6571df5647158afc083785a111 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Mon, 8 May 2017 15:41:35 -0230 Subject: [PATCH 02/24] Adds plumbing to enable DTrace instrumentation. Instrumentation using DTrace is modelled on that of KTrace. To enable you add the following your policy: dtrace: userspace The only two options supported right now are userspace and none (the default). --- src/Policy.cc | 10 ++++++++++ src/Policy.hh | 7 +++++++ src/PolicyFile.cc | 17 +++++++++++++++++ src/PolicyFile.hh | 2 ++ 4 files changed, 36 insertions(+) diff --git a/src/Policy.cc b/src/Policy.cc index 0bfd26c..3bb17a8 100644 --- a/src/Policy.cc +++ b/src/Policy.cc @@ -31,6 +31,7 @@ */ #include "KTraceLogger.hh" +#include "DTraceLogger.hh" #include "Policy.hh" using namespace llvm; using namespace loom; @@ -61,6 +62,15 @@ std::vector> Policy::Loggers(Module& Mod) const case Policy::KTraceTarget::None: break; } + + switch (this->DTrace()) { + case Policy::DTraceTarget::Userspace: + Loggers.emplace_back(new DTraceLogger(Mod)); + break; + + case Policy::DTraceTarget::None: + break; + } return Loggers; } diff --git a/src/Policy.hh b/src/Policy.hh index 0f199b1..3747111 100644 --- a/src/Policy.hh +++ b/src/Policy.hh @@ -76,6 +76,13 @@ class Policy //! Should we use ktrace logging? virtual KTraceTarget KTrace() const = 0; + + //! Ways that we can use DTrace (or not). + enum class DTraceTarget { Userspace, None }; + + //! Should we use ktrace logging? + virtual DTraceTarget DTrace() const = 0; + //! How should we serialize data? virtual std::unique_ptr Serialization(llvm::Module&) const = 0; diff --git a/src/PolicyFile.cc b/src/PolicyFile.cc index a102484..995d836 100644 --- a/src/PolicyFile.cc +++ b/src/PolicyFile.cc @@ -119,6 +119,9 @@ struct PolicyFile::PolicyFileData /// KTrace-based logging. Policy::KTraceTarget KTrace; + + /// DTrace-based logging. + Policy::DTraceTarget DTrace; /// Serialization. SerializationType Serial; @@ -172,6 +175,15 @@ struct yaml::ScalarEnumerationTraits { } }; +/// Converts an KTraceTarget to/from YAML. +template <> +struct yaml::ScalarEnumerationTraits { + static void enumeration(yaml::IO &io, Policy::DTraceTarget& T) { + io.enumCase(T, "userspace", Policy::DTraceTarget::Userspace); + io.enumCase(T, "none", Policy::DTraceTarget::None); + } +}; + /// Converts a Policy::Direction to/from YAML. template <> struct yaml::ScalarEnumerationTraits { @@ -244,6 +256,7 @@ struct yaml::MappingTraits { io.mapOptional("strategy", policy.Strategy, InstrStrategy::Kind::Callout); io.mapOptional("logging", policy.Logging, SimpleLogger::LogType::None); io.mapOptional("ktrace", policy.KTrace, Policy::KTraceTarget::None); + io.mapOptional("dtrace", policy.DTrace, Policy::DTraceTarget::None); io.mapOptional("serialization", policy.Serial, SerializationType::None); io.mapOptional("block_structure", policy.UseBlockStructure, false); io.mapOptional("hook_prefix", policy.HookPrefix, string("__loom")); @@ -305,6 +318,10 @@ Policy::KTraceTarget PolicyFile::KTrace() const return Policy->KTrace; } +Policy::DTraceTarget PolicyFile::DTrace() const +{ + return Policy->DTrace; +} unique_ptr PolicyFile::Serialization(Module& Mod) const { diff --git a/src/PolicyFile.hh b/src/PolicyFile.hh index e879f3c..25b30ad 100644 --- a/src/PolicyFile.hh +++ b/src/PolicyFile.hh @@ -55,6 +55,8 @@ class PolicyFile : public Policy SimpleLogger::LogType Logging() const override; KTraceTarget KTrace() const override; + + DTraceTarget DTrace() const override; std::unique_ptr Serialization(llvm::Module&) const override; From 21a8530fb2c98a68c27d969761b6114c534e440a Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Thu, 22 Jun 2017 10:53:38 -0230 Subject: [PATCH 03/24] Removes unnecessary dump() call. --- src/InstrStrategy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/InstrStrategy.cc b/src/InstrStrategy.cc index 83ae7e2..a27bc79 100644 --- a/src/InstrStrategy.cc +++ b/src/InstrStrategy.cc @@ -175,7 +175,7 @@ CalloutStrategy::Instrument(Instruction *I, StringRef Name, StringRef Descrip, EndBlock = FindBlock("exit", *InstrFn); } - InstrFn->dump(); + // InstrFn->dump(); // Call the instrumentation function: CallInst *Call = CallInst::Create(InstrFn, Values); From 9556a3968ecbad53df505147a28e3c66b4697f8d Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Thu, 22 Jun 2017 10:55:23 -0230 Subject: [PATCH 04/24] Fixes cut/paste error in a comment. --- src/PolicyFile.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PolicyFile.cc b/src/PolicyFile.cc index 995d836..c8206d9 100644 --- a/src/PolicyFile.cc +++ b/src/PolicyFile.cc @@ -175,7 +175,7 @@ struct yaml::ScalarEnumerationTraits { } }; -/// Converts an KTraceTarget to/from YAML. +/// Converts an DTraceTarget to/from YAML. template <> struct yaml::ScalarEnumerationTraits { static void enumeration(yaml::IO &io, Policy::DTraceTarget& T) { From 076f0ccd67e52b8a7d5641ff3a95fdb77f973fb4 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Thu, 22 Jun 2017 10:56:35 -0230 Subject: [PATCH 05/24] Working DTraceLogger that submits null pointers for testing. --- src/DTraceLogger.cc | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index 92284a9..f1002a8 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -32,15 +32,17 @@ #include "DTraceLogger.hh" +#include #include #include +#include using namespace loom; using namespace llvm; using std::vector; DTraceLogger::DTraceLogger(llvm::Module& Mod) - : Logger(Mod){}; + : Logger(Mod){ }; Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, StringRef Name, StringRef Descrip, @@ -50,19 +52,22 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, IRBuilder<> B(I); LLVMContext &Ctx = Mod.getContext(); - std::vector params = { TypeBuilder::get(Ctx), - TypeBuilder::get(Ctx), - TypeBuilder::get(Ctx), - TypeBuilder::get(Ctx), - TypeBuilder::get(Ctx), - TypeBuilder::get(Ctx)}; + Type* param = TypeBuilder::get(Ctx); + std::vector params = { param, param, param, param, param, param }; auto *FT = FunctionType::get( TypeBuilder::get(Ctx), params, false); Constant *F = Mod.getOrInsertFunction("dt_probe", FT); - ArrayRef args( Mod.getNamedValue(Name) ); + Value* args[6]; + for (int i = 0; i < 6; i++) + { + Value* ptr = ConstantInt::get( param , 0 ); + args[i] = ptr; + } - return B.CreateCall(F, args); + ArrayRef argsRef(args, 6); + + return B.CreateCall(F, argsRef); } From e943d268f785b0be455e88ed3156d17b03af1d79 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Tue, 27 Jun 2017 14:52:04 -0230 Subject: [PATCH 06/24] Handles variable arg lengths and pointer args. --- src/DTraceLogger.cc | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index f1002a8..2b7fc3f 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -32,6 +32,8 @@ #include "DTraceLogger.hh" +#include + #include #include #include @@ -53,19 +55,35 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, LLVMContext &Ctx = Mod.getContext(); Type* param = TypeBuilder::get(Ctx); - std::vector params = { param, param, param, param, param, param }; + + size_t n_args = std::min(Values.size(), 6ul); + + std::vector params; + for (int i = 0; i < n_args; i++) { + params.push_back(param); + } + auto *FT = FunctionType::get( TypeBuilder::get(Ctx), params, false); Constant *F = Mod.getOrInsertFunction("dt_probe", FT); + Value* args[6]; - for (int i = 0; i < 6; i++) + for (int i = 0; i < n_args; i++) { - Value* ptr = ConstantInt::get( param , 0 ); - args[i] = ptr; + Value *ptr; + + Type *T = Values[i]->getType(); + if (dyn_cast(T)) { + ptr = B.CreatePtrToInt(Values[i], param); + } else { + ptr = ConstantInt::get( param , 0 ); + } + + args[i] = ptr; } - ArrayRef argsRef(args, 6); + ArrayRef argsRef(args, n_args); return B.CreateCall(F, argsRef); From d76b47dcce188f7e61d37a778ff304f1ed646629 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Tue, 27 Jun 2017 15:21:47 -0230 Subject: [PATCH 07/24] Uses better way to check is Value is PointerType. --- src/DTraceLogger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index 2b7fc3f..fe5d6ff 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -74,7 +74,7 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, Value *ptr; Type *T = Values[i]->getType(); - if (dyn_cast(T)) { + if (T->isPointerTy()) { ptr = B.CreatePtrToInt(Values[i], param); } else { ptr = ConstantInt::get( param , 0 ); From f7cedf8a8334945a739fecccdfbd58c777299cb1 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Tue, 27 Jun 2017 16:16:32 -0230 Subject: [PATCH 08/24] Handles interger args by passing value not ptr. For now integer values are handed into dt_probe(...) call by value, instead of handing in a ptr to the variable. LLVM stores variables in registers by default and it does not look like it is always possible to get an address. --- src/DTraceLogger.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index fe5d6ff..b1a9f33 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -76,8 +76,10 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, Type *T = Values[i]->getType(); if (T->isPointerTy()) { ptr = B.CreatePtrToInt(Values[i], param); + } else if (T->isIntegerTy()) { + ptr = B.CreateSExt(Values[i], param); } else { - ptr = ConstantInt::get( param , 0 ); + ptr = ConstantInt::get(param , 0); } args[i] = ptr; From 16758f24d36edae38c45403afb697c53b699ac91 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Wed, 5 Jul 2017 18:38:50 -0230 Subject: [PATCH 09/24] Adds DTrace instrumentation of floats and doubles. Requires a change to libdtrace (dt_parser.c) to allow casting of arg0-9 to float/double. --- src/DTraceLogger.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index b1a9f33..9e0ad06 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -78,6 +78,11 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, ptr = B.CreatePtrToInt(Values[i], param); } else if (T->isIntegerTy()) { ptr = B.CreateSExt(Values[i], param); + } else if (T->isDoubleTy()) { + ptr = B.CreateBitCast(Values[i], TypeBuilder::get(Ctx)); + } else if (T->isFloatTy()) { + auto *BC = B.CreateBitCast(Values[i], TypeBuilder::get(Ctx)); + ptr = B.CreateSExt(BC, param); } else { ptr = ConstantInt::get(param , 0); } From 975ede8c1233fa83ae460359e5f03b2980410abf Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Thu, 11 Jan 2018 12:20:48 -0330 Subject: [PATCH 10/24] Adds config file options to instrument global variables. --- src/PolicyFile.cc | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/PolicyFile.cc b/src/PolicyFile.cc index c8206d9..dec5f54 100644 --- a/src/PolicyFile.cc +++ b/src/PolicyFile.cc @@ -71,21 +71,21 @@ struct FnInstrumentation Policy::Directions Body; }; -/// An operation that can be performed on a structure field -enum class FieldOperation +/// An operation that can be performed on a variable +enum class Operation { Read, Write, }; -/// A description of how to instrument a function. +/// A description of which operations to instrument on a structure field. struct FieldInstrumentation { /// Field name. string Name; /// Operations (read/write) that should be instrumented. - vector Operations; + vector Operations; }; /// Serialization strategies we can use (libnv, MessagePack, null...). @@ -104,6 +104,15 @@ struct StructInstrumentation vector Fields; }; +/// A description of how to instrumnt a global variables. +struct GlobalInstrumentation +{ + /// Name of the global variable to instrument + string Name; + + /// Operations (read/write) that should be instrumented. + vector Operations; +}; /// Everything contained in an instrumentation description file. struct PolicyFile::PolicyFileData @@ -137,6 +146,9 @@ struct PolicyFile::PolicyFileData /// Structure field instrumentation. vector Structures; + + /// Global variable insstrumentation. + vector Globals; }; @@ -222,12 +234,12 @@ struct yaml::MappingTraits { } }; -/// Converts a FieldOperation to/from YAML. +/// Converts a Operation to/from YAML. template <> -struct yaml::ScalarEnumerationTraits { - static void enumeration(yaml::IO &io, FieldOperation& Dir) { - io.enumCase(Dir, "read", FieldOperation::Read); - io.enumCase(Dir, "write", FieldOperation::Write); +struct yaml::ScalarEnumerationTraits { + static void enumeration(yaml::IO &io, Operation& Dir) { + io.enumCase(Dir, "read", Operation::Read); + io.enumCase(Dir, "write", Operation::Write); } }; @@ -249,6 +261,15 @@ struct yaml::MappingTraits { } }; +/// COnverts GlobalInstrumentation to/from YAML. +template<> +struct yaml::MappingTraits { + static void mapping(yaml::IO &io, GlobalInstrumentation &g) { + io.mapRequired("name", g.Name); + io.mapRequired("operations", g.Operations); + } +}; + /// Converts PolicyFileData to/from YAML. template <> struct yaml::MappingTraits { @@ -263,6 +284,7 @@ struct yaml::MappingTraits { io.mapOptional("everything", policy.InstrumentEverything, false); io.mapOptional("functions", policy.Functions); io.mapOptional("structures", policy.Structures); + io.mapOptional("globals", policy.Globals); } }; @@ -419,7 +441,7 @@ PolicyFile::FieldReadHook(const llvm::StructType& T, StringRef Field) const for (auto& F : S.Fields) { if (F.Name == Field) { - return vecContains(F.Operations, FieldOperation::Read); + return vecContains(F.Operations, Operation::Read); } } } @@ -445,7 +467,7 @@ PolicyFile::FieldWriteHook(const llvm::StructType& T, StringRef Field) const for (auto& F : S.Fields) { if (F.Name == Field) { - return vecContains(F.Operations, FieldOperation::Write); + return vecContains(F.Operations, Operation::Write); } } } From 91b052d368b4c713bf734eb82647be11f3209d6c Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Tue, 2 May 2017 11:16:57 -0230 Subject: [PATCH 11/24] Adds initial version of DTrace supports. --- scripts/loom-fbsdmake | 2 +- src/CMakeLists.txt | 1 + src/DTraceLogger.cc | 68 +++++++++++++++++++++++++++++++++++++++++++ src/DTraceLogger.hh | 59 +++++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/DTraceLogger.cc create mode 100644 src/DTraceLogger.hh diff --git a/scripts/loom-fbsdmake b/scripts/loom-fbsdmake index 1e146fb..55f26f7 100755 --- a/scripts/loom-fbsdmake +++ b/scripts/loom-fbsdmake @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/sh -x . `dirname $0`/xtools.sh diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 236a2c5..6a50904 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,6 @@ set(FILES DebugInfo + DTraceLogger Instrumentation Instrumenter InstrStrategy diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc new file mode 100644 index 0000000..92284a9 --- /dev/null +++ b/src/DTraceLogger.cc @@ -0,0 +1,68 @@ +//! @file DTraceLogger.cc Definition of @ref DTraceLogger. +/* + * Copyright (c) 2017 Brian Kidney + * All rights reserved. + * + * This software was developed by BAE Systems, the University of Cambridge + * Computer Laboratory, and Memorial University under DARPA/AFRL contract + * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing + * (TC) research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 "DTraceLogger.hh" + +#include +#include + +using namespace loom; +using namespace llvm; +using std::vector; + +DTraceLogger::DTraceLogger(llvm::Module& Mod) + : Logger(Mod){}; + +Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, + StringRef Name, StringRef Descrip, + bool /* SuppressUniqueness */) { + + + IRBuilder<> B(I); + + LLVMContext &Ctx = Mod.getContext(); + std::vector params = { TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx)}; + auto *FT = FunctionType::get( TypeBuilder::get(Ctx), params, false); + + Constant *F = Mod.getOrInsertFunction("dt_probe", FT); + + ArrayRef args( Mod.getNamedValue(Name) ); + + return B.CreateCall(F, args); + +} + diff --git a/src/DTraceLogger.hh b/src/DTraceLogger.hh new file mode 100644 index 0000000..0bcb04e --- /dev/null +++ b/src/DTraceLogger.hh @@ -0,0 +1,59 @@ +//! @file DTraceLogger.hh Declaration of @ref DTraceLogger. +/* + * Copyright (c) 2017 Brian Kidney + * All rights reserved. + * + * This software was developed by BAE Systems, the University of Cambridge + * Computer Laboratory, and Memorial University under DARPA/AFRL contract + * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing + * (TC) research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 DTRACE_LOGGER_H_ +#define DTRACE_LOGGER_H_ + +#include "Logger.hh" + +namespace loom { + +class Serializer; + +/** + * A logging technique that writes values to the DTrace framework using + * Userland Statically Defined Traces (USDT). libusdt is used to create probes + * at runtime. + */ +class DTraceLogger : public loom::Logger { +public: + DTraceLogger(llvm::Module& Mod); + + + virtual llvm::Value* Log(llvm::Instruction *I, llvm::ArrayRef Values, + llvm::StringRef Name, llvm::StringRef Descrip, + bool /* SuppressUniqueness */) override; +}; + +} // namespace loom + +#endif // !DTRACE_LOGGER_H_ From 290ddd8e01e7fbee55acfbb3a4c1aefaf1fd64ac Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Mon, 8 May 2017 15:41:35 -0230 Subject: [PATCH 12/24] Adds plumbing to enable DTrace instrumentation. Instrumentation using DTrace is modelled on that of KTrace. To enable you add the following your policy: dtrace: userspace The only two options supported right now are userspace and none (the default). --- src/Policy.cc | 11 +++++++++++ src/Policy.hh | 7 +++++++ src/PolicyFile.cc | 18 +++++++++++++++++- src/PolicyFile.hh | 2 ++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/Policy.cc b/src/Policy.cc index f07daeb..04fca1e 100644 --- a/src/Policy.cc +++ b/src/Policy.cc @@ -30,8 +30,10 @@ * SUCH DAMAGE. */ +#include "DTraceLogger.hh" #include "Policy.hh" #include "KTraceLogger.hh" + using namespace llvm; using namespace loom; using std::unique_ptr; @@ -61,6 +63,15 @@ std::vector> Policy::Loggers(Module &Mod) const { case Policy::KTraceTarget::None: break; } + + switch (this->DTrace()) { + case Policy::DTraceTarget::Userspace: + Loggers.emplace_back(new DTraceLogger(Mod)); + break; + + case Policy::DTraceTarget::None: + break; + } return Loggers; } diff --git a/src/Policy.hh b/src/Policy.hh index 3f4bf30..b47558a 100644 --- a/src/Policy.hh +++ b/src/Policy.hh @@ -84,6 +84,13 @@ public: //! Should we use ktrace logging? virtual KTraceTarget KTrace() const = 0; + + //! Ways that we can use DTrace (or not). + enum class DTraceTarget { Userspace, None }; + + //! Should we use ktrace logging? + virtual DTraceTarget DTrace() const = 0; + //! How should we serialize data? virtual std::unique_ptr Serialization(llvm::Module &) const = 0; diff --git a/src/PolicyFile.cc b/src/PolicyFile.cc index 791a171..155ae2c 100644 --- a/src/PolicyFile.cc +++ b/src/PolicyFile.cc @@ -139,6 +139,9 @@ struct PolicyFile::PolicyFileData { /// KTrace-based logging. Policy::KTraceTarget KTrace; + + /// DTrace-based logging. + Policy::DTraceTarget DTrace; /// Serialization. SerializationType Serial; @@ -194,6 +197,15 @@ template <> struct yaml::ScalarEnumerationTraits { } }; +/// Converts an DTraceTarget to/from YAML. +template <> +struct yaml::ScalarEnumerationTraits { + static void enumeration(yaml::IO &io, Policy::DTraceTarget& T) { + io.enumCase(T, "userspace", Policy::DTraceTarget::Userspace); + io.enumCase(T, "none", Policy::DTraceTarget::None); + } +}; + /// Converts a Policy::Direction to/from YAML. template <> struct yaml::ScalarEnumerationTraits { static void enumeration(yaml::IO &io, Policy::Direction &Dir) { @@ -278,6 +290,7 @@ template <> struct yaml::MappingTraits { io.mapOptional("strategy", policy.Strategy, InstrStrategy::Kind::Callout); io.mapOptional("logging", policy.Logging, SimpleLogger::LogType::None); io.mapOptional("ktrace", policy.KTrace, Policy::KTraceTarget::None); + io.mapOptional("dtrace", policy.DTrace, Policy::DTraceTarget::None); io.mapOptional("serialization", policy.Serial, SerializationType::None); io.mapOptional("block_structure", policy.UseBlockStructure, false); io.mapOptional("hook_prefix", policy.HookPrefix, string("__loom")); @@ -322,7 +335,10 @@ SimpleLogger::LogType PolicyFile::Logging() const { return Policy->Logging; } Policy::KTraceTarget PolicyFile::KTrace() const { return Policy->KTrace; } -unique_ptr PolicyFile::Serialization(Module &Mod) const { +Policy::DTraceTarget PolicyFile::DTrace() const { return Policy->DTrace; } + +unique_ptr PolicyFile::Serialization(Module& Mod) const +{ switch (Policy->Serial) { case SerializationType::LibNV: return unique_ptr(new NVSerializer(Mod)); diff --git a/src/PolicyFile.hh b/src/PolicyFile.hh index 2ef607b..05129ab 100644 --- a/src/PolicyFile.hh +++ b/src/PolicyFile.hh @@ -61,6 +61,8 @@ public: SimpleLogger::LogType Logging() const override; KTraceTarget KTrace() const override; + + DTraceTarget DTrace() const override; std::unique_ptr Serialization(llvm::Module &) const override; From 6ab4c5ab8062e8f58b379581509994ea47669624 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Thu, 22 Jun 2017 10:56:35 -0230 Subject: [PATCH 13/24] Working DTraceLogger that submits null pointers for testing. --- src/DTraceLogger.cc | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index 92284a9..f1002a8 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -32,15 +32,17 @@ #include "DTraceLogger.hh" +#include #include #include +#include using namespace loom; using namespace llvm; using std::vector; DTraceLogger::DTraceLogger(llvm::Module& Mod) - : Logger(Mod){}; + : Logger(Mod){ }; Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, StringRef Name, StringRef Descrip, @@ -50,19 +52,22 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, IRBuilder<> B(I); LLVMContext &Ctx = Mod.getContext(); - std::vector params = { TypeBuilder::get(Ctx), - TypeBuilder::get(Ctx), - TypeBuilder::get(Ctx), - TypeBuilder::get(Ctx), - TypeBuilder::get(Ctx), - TypeBuilder::get(Ctx)}; + Type* param = TypeBuilder::get(Ctx); + std::vector params = { param, param, param, param, param, param }; auto *FT = FunctionType::get( TypeBuilder::get(Ctx), params, false); Constant *F = Mod.getOrInsertFunction("dt_probe", FT); - ArrayRef args( Mod.getNamedValue(Name) ); + Value* args[6]; + for (int i = 0; i < 6; i++) + { + Value* ptr = ConstantInt::get( param , 0 ); + args[i] = ptr; + } - return B.CreateCall(F, args); + ArrayRef argsRef(args, 6); + + return B.CreateCall(F, argsRef); } From 5c336ca3905b3dd3cbebed9ccc18898c50b6f724 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Tue, 27 Jun 2017 14:52:04 -0230 Subject: [PATCH 14/24] Handles variable arg lengths and pointer args. --- src/DTraceLogger.cc | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index f1002a8..fe5d6ff 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -32,6 +32,8 @@ #include "DTraceLogger.hh" +#include + #include #include #include @@ -53,19 +55,35 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, LLVMContext &Ctx = Mod.getContext(); Type* param = TypeBuilder::get(Ctx); - std::vector params = { param, param, param, param, param, param }; + + size_t n_args = std::min(Values.size(), 6ul); + + std::vector params; + for (int i = 0; i < n_args; i++) { + params.push_back(param); + } + auto *FT = FunctionType::get( TypeBuilder::get(Ctx), params, false); Constant *F = Mod.getOrInsertFunction("dt_probe", FT); + Value* args[6]; - for (int i = 0; i < 6; i++) + for (int i = 0; i < n_args; i++) { - Value* ptr = ConstantInt::get( param , 0 ); - args[i] = ptr; + Value *ptr; + + Type *T = Values[i]->getType(); + if (T->isPointerTy()) { + ptr = B.CreatePtrToInt(Values[i], param); + } else { + ptr = ConstantInt::get( param , 0 ); + } + + args[i] = ptr; } - ArrayRef argsRef(args, 6); + ArrayRef argsRef(args, n_args); return B.CreateCall(F, argsRef); From 8c2e0101b11c8da95adf8dfef085e93b2577d729 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Tue, 27 Jun 2017 16:16:32 -0230 Subject: [PATCH 15/24] Handles interger args by passing value not ptr. For now integer values are handed into dt_probe(...) call by value, instead of handing in a ptr to the variable. LLVM stores variables in registers by default and it does not look like it is always possible to get an address. --- src/DTraceLogger.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index fe5d6ff..b1a9f33 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -76,8 +76,10 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, Type *T = Values[i]->getType(); if (T->isPointerTy()) { ptr = B.CreatePtrToInt(Values[i], param); + } else if (T->isIntegerTy()) { + ptr = B.CreateSExt(Values[i], param); } else { - ptr = ConstantInt::get( param , 0 ); + ptr = ConstantInt::get(param , 0); } args[i] = ptr; From 6e0f3ea1c4f4a575596fdacf07d383f85f6fdd3c Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Wed, 5 Jul 2017 18:38:50 -0230 Subject: [PATCH 16/24] Adds DTrace instrumentation of floats and doubles. Requires a change to libdtrace (dt_parser.c) to allow casting of arg0-9 to float/double. --- src/DTraceLogger.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index b1a9f33..9e0ad06 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -78,6 +78,11 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, ptr = B.CreatePtrToInt(Values[i], param); } else if (T->isIntegerTy()) { ptr = B.CreateSExt(Values[i], param); + } else if (T->isDoubleTy()) { + ptr = B.CreateBitCast(Values[i], TypeBuilder::get(Ctx)); + } else if (T->isFloatTy()) { + auto *BC = B.CreateBitCast(Values[i], TypeBuilder::get(Ctx)); + ptr = B.CreateSExt(BC, param); } else { ptr = ConstantInt::get(param , 0); } From 372e197398ab6d8eed190bbde7086a14298f3f04 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Tue, 22 Jan 2019 14:48:45 -0330 Subject: [PATCH 17/24] Updates DTraceLogger to use Metadata. --- src/DTraceLogger.cc | 8 ++++++-- src/DTraceLogger.hh | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index 9e0ad06..0a1248a 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -48,15 +48,18 @@ DTraceLogger::DTraceLogger(llvm::Module& Mod) Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, StringRef Name, StringRef Descrip, + Metadata Metadata, bool /* SuppressUniqueness */) { + if (not Metadata.isValid()) + errs() << "Warning: Dtrace Logger requires the use of Metadata to function properly."; IRBuilder<> B(I); LLVMContext &Ctx = Mod.getContext(); Type* param = TypeBuilder::get(Ctx); - size_t n_args = std::min(Values.size(), 6ul); + size_t n_args = std::min(Values.size(), 5ul); std::vector params; for (int i = 0; i < n_args; i++) { @@ -69,6 +72,7 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, Value* args[6]; + args[0] = B.CreateSExt(ConstantInt::get(TypeBuilder::get(Ctx), Metadata.Id), param);; for (int i = 0; i < n_args; i++) { Value *ptr; @@ -87,7 +91,7 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, ptr = ConstantInt::get(param , 0); } - args[i] = ptr; + args[i + 1] = ptr; } ArrayRef argsRef(args, n_args); diff --git a/src/DTraceLogger.hh b/src/DTraceLogger.hh index 0bcb04e..d67c0d0 100644 --- a/src/DTraceLogger.hh +++ b/src/DTraceLogger.hh @@ -51,6 +51,7 @@ public: virtual llvm::Value* Log(llvm::Instruction *I, llvm::ArrayRef Values, llvm::StringRef Name, llvm::StringRef Descrip, + Metadata Metadata, bool /* SuppressUniqueness */) override; }; From a3955f016173a45baed0be88d06600b841f249bd Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Wed, 27 Feb 2019 13:04:28 -0330 Subject: [PATCH 18/24] Changes DTrace logger to allow identifying probes. --- src/DTraceLogger.cc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index 0a1248a..7ffffb9 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -57,13 +57,14 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, IRBuilder<> B(I); LLVMContext &Ctx = Mod.getContext(); - Type* param = TypeBuilder::get(Ctx); + Type* id_t = TypeBuilder::get(Ctx); + Type* param_t = TypeBuilder::get(Ctx); size_t n_args = std::min(Values.size(), 5ul); std::vector params; - for (int i = 0; i < n_args; i++) { - params.push_back(param); + for (int i = 0; i < n_args + 1; i++) { + params.push_back(param_t); } auto *FT = FunctionType::get( TypeBuilder::get(Ctx), params, false); @@ -72,29 +73,29 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, Value* args[6]; - args[0] = B.CreateSExt(ConstantInt::get(TypeBuilder::get(Ctx), Metadata.Id), param);; + args[0] = B.CreateSExt(ConstantInt::get(id_t, Metadata.Id), param_t);; for (int i = 0; i < n_args; i++) { Value *ptr; Type *T = Values[i]->getType(); if (T->isPointerTy()) { - ptr = B.CreatePtrToInt(Values[i], param); + ptr = B.CreatePtrToInt(Values[i], param_t); } else if (T->isIntegerTy()) { - ptr = B.CreateSExt(Values[i], param); + ptr = B.CreateSExt(Values[i], param_t); } else if (T->isDoubleTy()) { ptr = B.CreateBitCast(Values[i], TypeBuilder::get(Ctx)); } else if (T->isFloatTy()) { auto *BC = B.CreateBitCast(Values[i], TypeBuilder::get(Ctx)); - ptr = B.CreateSExt(BC, param); + ptr = B.CreateSExt(BC, param_t); } else { - ptr = ConstantInt::get(param , 0); + ptr = ConstantInt::get(param_t, 0); } args[i + 1] = ptr; } - ArrayRef argsRef(args, n_args); + ArrayRef argsRef(args, n_args + 1); return B.CreateCall(F, argsRef); From af941c7a01a5258b993a63f6ed499ef9ea7c49b2 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Fri, 1 Mar 2019 14:40:59 -0330 Subject: [PATCH 19/24] Fixes copywrite header. --- src/Metadata.hh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Metadata.hh b/src/Metadata.hh index 3454e01..77918da 100644 --- a/src/Metadata.hh +++ b/src/Metadata.hh @@ -1,10 +1,12 @@ -//! @file Strings.hh Declaration of string manipulation functions. +//! @file Metadata.hh Declaration of policy metadata. /* - * Copyright (c) 2015 Jonathan Anderson + * Copyright (c) 2018 Brian Kidney * All rights reserved. * - * This software was developed at Memorial University under the - * NSERC Discovery program (RGPIN-2015-06048). + * This software was developed by BAE Systems, the University of Cambridge + * Computer Laboratory, and Memorial University under DARPA/AFRL contract + * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing + * (TC) research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions From d54a027bf3aabb4e7a93353bb47a80fd0fd9d216 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Fri, 1 Mar 2019 14:41:51 -0330 Subject: [PATCH 20/24] Adds new mechanism for tranforming intrumented values. - Initial example is to change fds to UUIDs. - This is specific to the FreeBSD OS with CADETS modifications for UUIDs. --- src/Transform.cc | 107 +++++++++++++++++++++++++++++++++++++++++++++++ src/Transform.hh | 69 ++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 src/Transform.cc create mode 100644 src/Transform.hh diff --git a/src/Transform.cc b/src/Transform.cc new file mode 100644 index 0000000..6525e2a --- /dev/null +++ b/src/Transform.cc @@ -0,0 +1,107 @@ +//! @file Transforms.cc Defines transforms that can be applied to IR Data. +/* + * Copyright (c) 2017 Brian Kidney + * All rights reserved. + * + * This software was developed by BAE Systems, the University of Cambridge + * Computer Laboratory, and Memorial University under DARPA/AFRL contract + * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing + * (TC) research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 "DTraceLogger.hh" + +#include + +#include +#include +#include +#include + +using namespace loom; +using namespace llvm; +using std::vector; + + +Value* Transform::CreateTransform(Instruction* I, Module& Mod, Value* V) { + + Value* call = V; + + if (this->Fn == "GetUUID") { + call = CreateUUIDTransform(I, Mod, V); + } else { + errs() << "Warning: Dtrace Logger requires the use of Metadata to function properly."; + call = nullptr; + } + + return call; +} + +/* Length of a node address (an IEEE 802 address). */ +/* #define _UUID_NODE_LEN 6 */ +/* struct uuid { */ +/* uint32_t time_low; */ +/* uint16_t time_mid; */ +/* uint16_t time_hi_and_version; */ +/* uint8_t clock_seq_hi_and_reserved; */ +/* uint8_t clock_seq_low; */ +/* uint8_t node[_UUID_NODE_LEN]; */ +/* } */ + +/* int fgetuuid(int, struct uuid *); */ + +Value* Transform::CreateUUIDTransform(Instruction* I, Module& Mod, Value* V) { + + IRBuilder<> B(I); + + LLVMContext &Ctx = Mod.getContext(); + Type* fd_t = TypeBuilder::get(Ctx); + Type* uuid_t = StructType::get( TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx), + TypeBuilder::get(Ctx)); + + + Value* args[2]; + args[0] = V; + args[1] = B.CreateAlloca(uuid_t); + ArrayRef argsRef(args, 2); + + std::vector params; + params.push_back(fd_t); + params.push_back(args[1]->getType()); + + auto *FT = FunctionType::get( TypeBuilder::get(Ctx), params, false); + + Constant *F = Mod.getOrInsertFunction("fgetuuid", FT); + + + B.CreateCall(F, argsRef); + + return argsRef.data()[1]; + +} + diff --git a/src/Transform.hh b/src/Transform.hh new file mode 100644 index 0000000..813ad9b --- /dev/null +++ b/src/Transform.hh @@ -0,0 +1,69 @@ +//! @file Transform.hh Declaration of logging transforms. +/* + * Copyright (c) 2019 Brian Kidney + * All rights reserved. + * + * This software was developed by BAE Systems, the University of Cambridge + * Computer Laboratory, and Memorial University under DARPA/AFRL contract + * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing + * (TC) research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 LOOM_TRANSFORM_H +#define LOOM_TRANSFORM_H + + +namespace loom { + + //! Transforms to be applied during the instrumentation + class Transform { + + public: + Transform(std::string fn = "", int i = 0) { + Arg = i; + Fn = fn; + } + + bool isValid() { + if (Fn.empty() and Arg == 0) { + return false; + } + return true; + } + + unsigned int Arg; + std::string Fn; + + llvm::Value* CreateTransform(llvm::Instruction*, llvm::Module&, llvm::Value*); + + private: + llvm::Value* CreateUUIDTransform(llvm::Instruction*, llvm::Module&, llvm::Value*); + + }; + + + +} // namespace loom + +#endif /* LOOM_TRANSFORMS_H */ From e168e2628bf97c57e533007cdee3f2bfa58bd51c Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Fri, 1 Mar 2019 14:44:42 -0330 Subject: [PATCH 21/24] Adds Transform.{cc,hh} to the build. --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6a50904..aec49f6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,7 @@ set(FILES PolicyFile Serializer Strings + Transform ) foreach(base IN LISTS FILES) From 0ed581bf4757b6c04817497ad5719e8fbda07b20 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Fri, 1 Mar 2019 14:47:25 -0330 Subject: [PATCH 22/24] Adds transform functionality to Policy files and Loggers. - Initially no loggers are using this feature. --- src/DTraceLogger.cc | 2 +- src/DTraceLogger.hh | 2 +- src/InstrStrategy.cc | 23 +++++++++++++---------- src/InstrStrategy.hh | 5 ++--- src/Instrumenter.cc | 40 +++++++++++++++++++++------------------- src/Instrumenter.hh | 17 +++++++++-------- src/KTraceLogger.cc | 2 +- src/KTraceLogger.hh | 2 +- src/Logger.cc | 18 ++++++++++-------- src/Logger.hh | 6 ++++-- src/OptPass.cc | 10 +++++++++- src/Policy.hh | 5 +++++ src/PolicyFile.cc | 22 ++++++++++++++++++++++ src/PolicyFile.hh | 2 ++ 14 files changed, 101 insertions(+), 55 deletions(-) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index 7ffffb9..68b416c 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -48,7 +48,7 @@ DTraceLogger::DTraceLogger(llvm::Module& Mod) Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, StringRef Name, StringRef Descrip, - Metadata Metadata, + Metadata Metadata, std::vector Transforms, bool /* SuppressUniqueness */) { if (not Metadata.isValid()) diff --git a/src/DTraceLogger.hh b/src/DTraceLogger.hh index d67c0d0..60aaa93 100644 --- a/src/DTraceLogger.hh +++ b/src/DTraceLogger.hh @@ -51,7 +51,7 @@ public: virtual llvm::Value* Log(llvm::Instruction *I, llvm::ArrayRef Values, llvm::StringRef Name, llvm::StringRef Descrip, - Metadata Metadata, + Metadata Metadata, std::vector Transforms, bool /* SuppressUniqueness */) override; }; diff --git a/src/InstrStrategy.cc b/src/InstrStrategy.cc index 47c4c2a..623bff1 100644 --- a/src/InstrStrategy.cc +++ b/src/InstrStrategy.cc @@ -43,7 +43,6 @@ #include "InstrStrategy.hh" #include "Instrumentation.hh" -#include "Metadata.hh" using namespace llvm; using namespace loom; @@ -58,7 +57,8 @@ class CalloutStrategy : public InstrStrategy { Instrumentation Instrument(Instruction *I, StringRef Name, StringRef Descrip, ArrayRef Params, ArrayRef Values, loom::Metadata Md, - bool VarArgs, bool AfterInst, bool) override; + std::vector Transforms, bool VarArgs, + bool AfterInst, bool) override; }; class InlineStrategy : public InstrStrategy { @@ -68,8 +68,8 @@ class InlineStrategy : public InstrStrategy { Instrumentation Instrument(Instruction *I, StringRef Name, StringRef Descrip, ArrayRef Params, ArrayRef Values, loom::Metadata Md, - bool VarArgs, bool AfterInst, - bool SuppressInstrumentation) override; + std::vector Transforms, bool VarArgs, + bool AfterInst, bool SuppressInstrumentation) override; }; } // anonymous namespace @@ -93,12 +93,13 @@ void InstrStrategy::AddLogger(unique_ptr L) { Value *InstrStrategy::AddLogging(Instruction *I, ArrayRef Values, StringRef Name, StringRef Description, - loom::Metadata Md, bool SuppressUniqueness) { + loom::Metadata Md, std::vector Transforms, + bool SuppressUniqueness) { Value *End = nullptr; for (auto &L : Loggers) { assert(L); - End = L->Log(I, Values, Name, Description, Md, SuppressUniqueness); + End = L->Log(I, Values, Name, Description, Md, Transforms, SuppressUniqueness); } return End; @@ -108,7 +109,8 @@ Instrumentation CalloutStrategy::Instrument(Instruction *I, StringRef Name, StringRef Descrip, ArrayRef Params, ArrayRef Values, - loom::Metadata Md, bool VarArgs, + loom::Metadata Md, + std::vector Transforms, bool VarArgs, bool AfterInst, bool SuppressUniq) { Module *M = I->getModule(); @@ -158,7 +160,7 @@ Instrumentation CalloutStrategy::Instrument(Instruction *I, StringRef Name, End = PreambleEnd; } - AddLogging(PreambleEnd, InstrValues, Name, Descrip, Md, SuppressUniq); + AddLogging(PreambleEnd, InstrValues, Name, Descrip, Md, Transforms, SuppressUniq); // Also set instrumentation function's parameter names: size_t i = 0; @@ -192,7 +194,8 @@ Instrumentation InlineStrategy::Instrument(Instruction *I, StringRef Name, StringRef Descrip, ArrayRef Params, ArrayRef Values, - loom::Metadata Md, bool VarArgs, + loom::Metadata Md, + std::vector Transforms, bool VarArgs, bool AfterInst, bool SuppressUniq) { BasicBlock *BB = I->getParent(); @@ -238,7 +241,7 @@ Instrumentation InlineStrategy::Instrument(Instruction *I, StringRef Name, End = I; } - AddLogging(PreambleEnd, Values, Name, Descrip, Md, SuppressUniq); + AddLogging(PreambleEnd, Values, Name, Descrip, Md, Transforms, SuppressUniq); SmallVector V(Values.begin(), Values.end()); diff --git a/src/InstrStrategy.hh b/src/InstrStrategy.hh index 41390a9..6182331 100644 --- a/src/InstrStrategy.hh +++ b/src/InstrStrategy.hh @@ -41,7 +41,6 @@ #include "IRUtils.hh" #include "Logger.hh" -#include "Metadata.hh" namespace llvm { class Instruction; @@ -127,7 +126,7 @@ public: Instrument(llvm::Instruction *I, llvm::StringRef Name, llvm::StringRef Description, llvm::ArrayRef Params, llvm::ArrayRef Values, - Metadata Md, bool VarArgs = false, + Metadata Md, std::vector Tf, bool VarArgs = false, bool AfterInst = false, bool SuppressUniqueness = false) = 0; bool Initialize(llvm::Function &main); @@ -143,7 +142,7 @@ protected: */ llvm::Value *AddLogging(llvm::Instruction *I, llvm::ArrayRef, llvm::StringRef Name, llvm::StringRef Description, - Metadata Md, bool SuppressUniqueness); + Metadata Md, std::vector Tf, bool SuppressUniqueness); /** * Use an explicit structure of premable/instrumentation/end BasicBlocks diff --git a/src/Instrumenter.cc b/src/Instrumenter.cc index d3c7422..178c43e 100644 --- a/src/Instrumenter.cc +++ b/src/Instrumenter.cc @@ -40,7 +40,6 @@ #include "Instrumenter.hh" #include "Logger.hh" -#include "Metadata.hh" #include #include @@ -64,7 +63,7 @@ Instrumenter::Instrumenter(llvm::Module &Mod, NameFn NF, unique_ptr S) : Mod(Mod), Strategy(std::move(S)), Name(NF) {} -bool Instrumenter::Instrument(llvm::Instruction *I, loom::Metadata Md) { +bool Instrumenter::Instrument(llvm::Instruction *I, loom::Metadata Md, std::vector Transforms) { // If this instruction terminates a block, we need to treat it a bit // differently, placing instrumentation before it rather than after. const bool Terminator = I->isTerminator(); @@ -133,8 +132,8 @@ bool Instrumenter::Instrument(llvm::Instruction *I, loom::Metadata Md) { NameBuilder << static_cast(I); const string Name = NameBuilder.str(); - Strategy->Instrument(I, Name, Name, ValueDescriptions, Values, Md, Varargs, - AfterInst, true); + Strategy->Instrument(I, Name, Name, ValueDescriptions, Values, Md, Transforms, + Varargs, AfterInst, true); return true; } @@ -143,7 +142,8 @@ bool Instrumenter::Instrument(llvm::Instruction *I, loom::Metadata Md) { // instead of the bitcode name bool Instrumenter::InstrumentPtrInsts(llvm::Instruction *I, const llvm::DIVariable *Var, - loom::Metadata Md) { + loom::Metadata Md, + std::vector Transforms) { std::ostringstream LocationBuilder; @@ -271,24 +271,24 @@ bool Instrumenter::InstrumentPtrInsts(llvm::Instruction *I, const string InstrName = Name({"instruction", NameBuilder.str()}); Strategy->Instrument(I, InstrName, FormatStringPrefix, ValueDescriptions, - Values, Md, Varargs, AfterInst, true); + Values, Md, Transforms, Varargs, AfterInst, true); return true; } bool Instrumenter::Instrument(CallInst *Call, const Policy::Directions &D, - loom::Metadata Md) { + loom::Metadata Md, std::vector Transforms) { bool ModifiedIR = false; for (auto Dir : D) { - ModifiedIR |= Instrument(Call, Dir, Md); + ModifiedIR |= Instrument(Call, Dir, Md, Transforms); } return ModifiedIR; } bool Instrumenter::Instrument(llvm::CallInst *Call, Policy::Direction Dir, - loom::Metadata Md) { + loom::Metadata Md, std::vector Transforms) { Function *Target = Call->getCalledFunction(); assert(Target); // TODO: support indirect targets, too @@ -316,24 +316,24 @@ bool Instrumenter::Instrument(llvm::CallInst *Call, Policy::Direction Dir, bool InstrAfterCall = Return; Strategy->Instrument(Call, InstrName, FormatStringPrefix, Parameters, - Arguments, Md, VarArgs, InstrAfterCall); + Arguments, Md, Transforms, VarArgs, InstrAfterCall); return true; } bool Instrumenter::Instrument(Function &Fn, const Policy::Directions &D, - loom::Metadata Md) { + loom::Metadata Md, std::vector Transforms) { bool ModifiedIR = false; for (auto Dir : D) { - ModifiedIR |= Instrument(Fn, Dir, Md); + ModifiedIR |= Instrument(Fn, Dir, Md, Transforms); } return ModifiedIR; } bool Instrumenter::Instrument(Function &Fn, Policy::Direction Dir, - loom::Metadata Md) { + loom::Metadata Md, std::vector Transforms) { const bool Return = (Dir == Policy::Direction::Out); const string Description = Return ? "leave" : "enter"; StringRef FnName = Fn.getName(); @@ -386,7 +386,7 @@ bool Instrumenter::Instrument(Function &Fn, Policy::Direction Dir, } Strategy->Instrument(Ret, InstrName, FormatStringPrefix, InstrParameters, - Arguments, Md, VarArgs); + Arguments, Md, Transforms, VarArgs); } } else { @@ -395,14 +395,15 @@ bool Instrumenter::Instrument(Function &Fn, Policy::Direction Dir, BasicBlock &Entry = Fn.getBasicBlockList().front(); Strategy->Instrument(&Entry.front(), InstrName, FormatStringPrefix, - InstrParameters, Arguments, Md, VarArgs); + InstrParameters, Arguments, Md, Transforms, VarArgs); } return true; } bool Instrumenter::Instrument(GetElementPtrInst *GEP, LoadInst *Load, - StringRef FieldName, loom::Metadata Md) { + StringRef FieldName, loom::Metadata Md, + std::vector Transforms) { StructType *SourceType = dyn_cast(GEP->getSourceElementType()); assert(SourceType); assert(SourceType->getName().startswith("struct.")); @@ -425,13 +426,14 @@ bool Instrumenter::Instrument(GetElementPtrInst *GEP, LoadInst *Load, (StructName + "." + FieldName + " load:").str(); Strategy->Instrument(Load, InstrName, FormatStringPrefix, Parameters, - Arguments, Md, false, true); + Arguments, Md, Transforms, false, true); return true; } bool Instrumenter::Instrument(GetElementPtrInst *GEP, StoreInst *Store, - StringRef FieldName, loom::Metadata Md) { + StringRef FieldName, loom::Metadata Md, + std::vector Transforms) { StructType *SourceType = dyn_cast(GEP->getSourceElementType()); assert(SourceType); assert(SourceType->getName().startswith("struct.")); @@ -454,7 +456,7 @@ bool Instrumenter::Instrument(GetElementPtrInst *GEP, StoreInst *Store, (StructName + "." + FieldName + " store:").str(); Strategy->Instrument(Store, InstrName, FormatStringPrefix, Parameters, - Arguments, Md); + Arguments, Md, Transforms); return true; } diff --git a/src/Instrumenter.hh b/src/Instrumenter.hh index 4ba033b..c64a165 100644 --- a/src/Instrumenter.hh +++ b/src/Instrumenter.hh @@ -1,6 +1,7 @@ //! @file Instrumenter.hh Declaration of @ref loom::Instrumenter. /* * Copyright (c) 2016 Jonathan Anderson + * Copyright (c) 2018 Brian Kidney * All rights reserved. * * This software was developed by BAE Systems, the University of Cambridge @@ -70,36 +71,36 @@ public: std::unique_ptr); /// Instrument an instruction generically: instruction name and values. - bool Instrument(llvm::Instruction *, Metadata = Metadata()); + bool Instrument(llvm::Instruction *, Metadata = Metadata(), std::vector = std::vector()); /// Instrument an instruction generically with better info: instruction type /// and values. bool InstrumentPtrInsts(llvm::Instruction *, const llvm::DIVariable *, - Metadata = Metadata()); + Metadata = Metadata(), std::vector = std::vector()); /// Instrument a function call in the call and/or return direction. bool Instrument(llvm::CallInst *, const Policy::Directions &, - Metadata = Metadata()); + Metadata = Metadata(), std::vector = std::vector()); /// Instrument a function call (caller-side), either calling or returning. bool Instrument(llvm::CallInst *Call, Policy::Direction, - Metadata = Metadata()); + Metadata = Metadata(), std::vector = std::vector()); /// Instrument a function entry and/or exit. bool Instrument(llvm::Function &, const Policy::Directions &, - Metadata = Metadata()); + Metadata = Metadata(), std::vector = std::vector()); /// Instrument a function entry or exit. bool Instrument(llvm::Function &, Policy::Direction, - Metadata = Metadata()); + Metadata = Metadata(), std::vector = std::vector()); /// Instrument a read from a structure field. bool Instrument(llvm::GetElementPtrInst *, llvm::LoadInst *, - llvm::StringRef FieldName, Metadata = Metadata()); + llvm::StringRef FieldName, Metadata = Metadata(), std::vector = std::vector()); /// Instrument a write to a structure field. bool Instrument(llvm::GetElementPtrInst *, llvm::StoreInst *, - llvm::StringRef FieldName, Metadata = Metadata()); + llvm::StringRef FieldName, Metadata = Metadata(), std::vector = std::vector()); /// Add initialization required by Loggers bool InitializeLoggers(llvm::Function &); diff --git a/src/KTraceLogger.cc b/src/KTraceLogger.cc index a8ecfb1..efc3be3 100644 --- a/src/KTraceLogger.cc +++ b/src/KTraceLogger.cc @@ -47,7 +47,7 @@ KTraceLogger::KTraceLogger(Module &Mod, std::unique_ptr S, bool K) Value *KTraceLogger::Log(Instruction *I, ArrayRef Values, StringRef Name, StringRef Descrip, loom::Metadata Md, - bool /* SuppressUniqueness */) { + std::vector Transforms, bool /* SuppressUniqueness */) { IRBuilder<> B(I); diff --git a/src/KTraceLogger.hh b/src/KTraceLogger.hh index 95029dd..afacc67 100644 --- a/src/KTraceLogger.hh +++ b/src/KTraceLogger.hh @@ -51,7 +51,7 @@ public: virtual llvm::Value *Log(llvm::Instruction *, llvm::ArrayRef, llvm::StringRef Name, llvm::StringRef Descrip, - loom::Metadata Md, + loom::Metadata Md, std::vector Transforms, bool SuppressUniqueness) override; private: diff --git a/src/Logger.cc b/src/Logger.cc index 83790ae..ee2e491 100644 --- a/src/Logger.cc +++ b/src/Logger.cc @@ -35,8 +35,6 @@ #include #include -//#include - #include using namespace llvm; @@ -54,7 +52,8 @@ class LibxoLogger : public SimpleLogger { StringRef FunctionName() const override { return "xo_emit"; } Value *CreateFormatString(IRBuilder<> &, StringRef Prefix, ArrayRef Params, StringRef Suffix, - loom::Metadata Md, bool SuppressUniq) override; + loom::Metadata Md, + bool SuppressUniq) override; }; //! A logger that calls `printf()`. @@ -65,7 +64,8 @@ class PrintfLogger : public SimpleLogger { StringRef FunctionName() const override { return "printf"; } Value *CreateFormatString(IRBuilder<> &, StringRef Prefix, ArrayRef Params, StringRef Suffix, - loom::Metadata Md, bool SuppressUniq) override; + loom::Metadata Md, + bool SuppressUniq) override; }; } // anonymous namespace @@ -91,16 +91,18 @@ unique_ptr SimpleLogger::Create(Module &Mod, LogType Log) { Value *SimpleLogger::Log(Instruction *I, ArrayRef Values, StringRef /*Name*/, StringRef Description, - loom::Metadata Md, bool SuppressUniqueness) { + loom::Metadata Md, std::vector Transforms, + bool SuppressUniqueness) { // Call the printf-like logging function, ignoring the machine-readable name. IRBuilder<> B(I); - return Call(B, Description, Values, "\n", Md, SuppressUniqueness); + return Call(B, Description, Values, "\n", Md, Transforms, SuppressUniqueness); } CallInst *SimpleLogger::Call(IRBuilder<> &Builder, StringRef Prefix, ArrayRef Values, StringRef Suffix, - loom::Metadata Md, bool SuppressUniqueness) { + loom::Metadata Md, std::vector Transforms, + bool SuppressUniqueness) { vector Args = Adapt(Values, Builder); @@ -142,7 +144,7 @@ vector SimpleLogger::Adapt(ArrayRef Values, IRBuilder<> &B) { Value *LibxoLogger::CreateFormatString(IRBuilder<> &Builder, StringRef Prefix, ArrayRef Values, StringRef Suffix, loom::Metadata Md, - bool SuppressUniqueness) { + bool SuppressUniqueness) { std::stringstream FormatString; diff --git a/src/Logger.hh b/src/Logger.hh index b57f82c..3f9d6c6 100644 --- a/src/Logger.hh +++ b/src/Logger.hh @@ -35,6 +35,7 @@ #include "IRUtils.hh" #include "Metadata.hh" +#include "Transform.hh" #include @@ -72,7 +73,7 @@ public: virtual llvm::Value *Log(llvm::Instruction *I, llvm::ArrayRef Values, llvm::StringRef Name, llvm::StringRef Description, - Metadata Metadata, + Metadata Metadata, std::vector Transforms, bool SuppressUniqueness) = 0; virtual bool HasInitialization(); @@ -109,13 +110,14 @@ public: virtual llvm::Value *Log(llvm::Instruction *I, llvm::ArrayRef Values, llvm::StringRef Name, llvm::StringRef Description, - Metadata Metadata, + Metadata Metadata, std::vector Transforms, bool SuppressUniqueness) override; /// Log a set of values, with optional prefix and suffix text. llvm::CallInst *Call(llvm::IRBuilder<> &, llvm::StringRef FormatStringPrefix, llvm::ArrayRef Values, llvm::StringRef Suffix, Metadata Metadata, + std::vector Transforms, bool SuppressUniqueness = false); protected: diff --git a/src/OptPass.cc b/src/OptPass.cc index 73c52d8..c1425f8 100644 --- a/src/OptPass.cc +++ b/src/OptPass.cc @@ -2,6 +2,7 @@ /* * Copyright (c) 2016 Jonathan Anderson * Copyright (c) 2016 Cem Kilic + * Copyright (c) 2018 Brian Kidney * All rights reserved. * * This software was developed by BAE Systems, the University of Cambridge @@ -44,6 +45,7 @@ #include "Instrumenter.hh" #include "PolicyFile.hh" #include "Metadata.hh" +#include "Transform.hh" #include "llvm/IR/InstIterator.h" #include "llvm/IR/Module.h" @@ -112,6 +114,7 @@ bool OptPass::runOnModule(Module &Mod) { std::unordered_map Functions; std::unordered_map FnMetadata; + std::unordered_map> FnTransforms; std::unordered_map Calls; typedef std::pair NamedGEP; @@ -140,6 +143,10 @@ bool OptPass::runOnModule(Module &Mod) { if (not Md.Name.empty() && not Md.Id == 0) { FnMetadata.emplace(&Fn, Md); } + auto Transforms = P.InstrTransforms(Fn); + if (not Md.Name.empty() && not Md.Id == 0) { + FnTransforms.emplace(&Fn, Transforms); + } } for (auto &Inst : instructions(Fn)) { @@ -276,7 +283,8 @@ bool OptPass::runOnModule(Module &Mod) { for (auto &i : Functions) { auto Md = FnMetadata[i.first]; - ModifiedIR |= Instr->Instrument(*i.first, i.second, Md); + auto Transforms = FnTransforms[i.first]; + ModifiedIR |= Instr->Instrument(*i.first, i.second, Md, Transforms); } for (auto &i : Calls) { diff --git a/src/Policy.hh b/src/Policy.hh index b47558a..72f3db7 100644 --- a/src/Policy.hh +++ b/src/Policy.hh @@ -44,6 +44,7 @@ #include "InstrStrategy.hh" #include "Serializer.hh" #include "Metadata.hh" +#include "Transform.hh" #include #include @@ -119,7 +120,11 @@ public: //! In which directions (preamble/return) should a function be instrumented? virtual Directions FnHooks(const llvm::Function &) const = 0; + //! Return any metadata defined for an instruction virtual Metadata InstrMetadata(const llvm::Function &Fn) const = 0; + + //! Return any transforms defined for an instruction + virtual std::vector InstrTransforms(const llvm::Function &Fn) const = 0; /** * A structure type is relevant in some way to instrumentation. diff --git a/src/PolicyFile.cc b/src/PolicyFile.cc index 155ae2c..fbb6858 100644 --- a/src/PolicyFile.cc +++ b/src/PolicyFile.cc @@ -82,6 +82,9 @@ struct FnInstrumentation { /// Additional information about the function call loom::Metadata Meta; + + /// Additions transformations that should be applied when logging function call. + vector Transforms; }; /// An operation that can be performed on a variable @@ -222,6 +225,14 @@ template <> struct yaml::MappingTraits { } }; +/// Converts a Policy::Transforms to/from YAML. +template <> struct yaml::MappingTraits { + static void mapping(yaml::IO &io, loom::Transform &Transform) { + io.mapOptional("arg", Transform.Arg); + io.mapOptional("fn", Transform.Fn); + } +}; + /// Converts a SerializationType to/from YAML. template <> struct yaml::ScalarEnumerationTraits { static void enumeration(yaml::IO &io, SerializationType &S) { @@ -247,6 +258,7 @@ template <> struct yaml::MappingTraits { io.mapOptional("caller", fn.Call); io.mapOptional("callee", fn.Body); io.mapOptional("metadata", fn.Meta); + io.mapOptional("transforms", fn.Transforms); } }; @@ -398,6 +410,16 @@ loom::Metadata PolicyFile::InstrMetadata(const llvm::Function &Fn) const { } } +vector PolicyFile::InstrTransforms(const llvm::Function &Fn) const { + StringRef Name = Fn.getName(); + + for (FnInstrumentation &F : Policy->Functions) { + if (MatchName(F.Name, Name)) { + return F.Transforms; + } + } +} + bool PolicyFile::StructTypeMatters(const llvm::StructType &T) const { if (not T.hasName()) { return false; diff --git a/src/PolicyFile.hh b/src/PolicyFile.hh index 05129ab..5e4940e 100644 --- a/src/PolicyFile.hh +++ b/src/PolicyFile.hh @@ -77,6 +77,8 @@ public: Policy::Directions FnHooks(const llvm::Function &) const override; Metadata InstrMetadata(const llvm::Function &Fn) const override; + + std::vector InstrTransforms(const llvm::Function &Fn) const override; bool StructTypeMatters(const llvm::StructType &) const override; From 860160d68cbdb3b514b0384f2a660d2055b31831 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Fri, 1 Mar 2019 14:48:19 -0330 Subject: [PATCH 23/24] Make use of transforms in DTraceLogger. - This is being used to convert fds to UUIDs. - If there is a Transform defined for an arguments, it is applied and the result is passed to DTrace. --- src/DTraceLogger.cc | 46 +++++++++++++++++++++++++++++++-------------- src/DTraceLogger.hh | 3 +++ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index 68b416c..4675cee 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -46,6 +46,24 @@ using std::vector; DTraceLogger::DTraceLogger(llvm::Module& Mod) : Logger(Mod){ }; +Value* DTraceLogger::ConvertValueToPtr(IRBuilder<>& B, LLVMContext& Ctx, Value* V, Type* param_t) +{ + Type *T = V->getType(); + if (T->isPointerTy()) { + return B.CreatePtrToInt(V, param_t); + } else if (T->isIntegerTy()) { + return B.CreateSExt(V, param_t); + } else if (T->isDoubleTy()) { + return B.CreateBitCast(V, TypeBuilder::get(Ctx)); + } else if (T->isFloatTy()) { + auto *BC = B.CreateBitCast(V, TypeBuilder::get(Ctx)); + return B.CreateSExt(BC, param_t); + } + return ConstantInt::get(param_t, 0); +} + + + Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, StringRef Name, StringRef Descrip, Metadata Metadata, std::vector Transforms, @@ -78,20 +96,20 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, { Value *ptr; - Type *T = Values[i]->getType(); - if (T->isPointerTy()) { - ptr = B.CreatePtrToInt(Values[i], param_t); - } else if (T->isIntegerTy()) { - ptr = B.CreateSExt(Values[i], param_t); - } else if (T->isDoubleTy()) { - ptr = B.CreateBitCast(Values[i], TypeBuilder::get(Ctx)); - } else if (T->isFloatTy()) { - auto *BC = B.CreateBitCast(Values[i], TypeBuilder::get(Ctx)); - ptr = B.CreateSExt(BC, param_t); - } else { - ptr = ConstantInt::get(param_t, 0); - } - + Transform Tf; + for (auto t: Transforms) { + if (t.Arg == i) + Tf = t; + break; + } + + if (Tf.isValid()) { + errs() << "Transforming argument " << Tf.Arg << " with function " << Tf.Fn << "\n"; + ptr = ConvertValueToPtr(B, Ctx, Tf.CreateTransform(I, Mod, Values[i]), param_t); + } else { + ptr = ConvertValueToPtr(B, Ctx, Values[i], param_t); + } + args[i + 1] = ptr; } diff --git a/src/DTraceLogger.hh b/src/DTraceLogger.hh index 60aaa93..fd06413 100644 --- a/src/DTraceLogger.hh +++ b/src/DTraceLogger.hh @@ -53,6 +53,9 @@ public: llvm::StringRef Name, llvm::StringRef Descrip, Metadata Metadata, std::vector Transforms, bool /* SuppressUniqueness */) override; +private: + llvm::Value* ConvertValueToPtr(llvm::IRBuilder<>&, llvm::LLVMContext&, llvm::Value*, llvm::Type*); + }; } // namespace loom From eea8d98fed5d1409c57c49f2529cef1ab617fbd8 Mon Sep 17 00:00:00 2001 From: Brian Kidney Date: Fri, 1 Mar 2019 15:04:17 -0330 Subject: [PATCH 24/24] Removes debug message. --- src/DTraceLogger.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DTraceLogger.cc b/src/DTraceLogger.cc index 4675cee..453385a 100644 --- a/src/DTraceLogger.cc +++ b/src/DTraceLogger.cc @@ -104,7 +104,6 @@ Value* DTraceLogger::Log(Instruction *I, ArrayRef Values, } if (Tf.isValid()) { - errs() << "Transforming argument " << Tf.Arg << " with function " << Tf.Fn << "\n"; ptr = ConvertValueToPtr(B, Ctx, Tf.CreateTransform(I, Mod, Values[i]), param_t); } else { ptr = ConvertValueToPtr(B, Ctx, Values[i], param_t);