diff --git a/llvm/bindings/go/llvm/InstrumentationBindings.h b/llvm/bindings/go/llvm/InstrumentationBindings.h deleted file mode 100644 --- a/llvm/bindings/go/llvm/InstrumentationBindings.h +++ /dev/null @@ -1,37 +0,0 @@ -//===- InstrumentationBindings.h - instrumentation bindings -----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines C bindings for the Transforms/Instrumentation component. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_BINDINGS_GO_LLVM_INSTRUMENTATIONBINDINGS_H -#define LLVM_BINDINGS_GO_LLVM_INSTRUMENTATIONBINDINGS_H - -#include "llvm-c/Core.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// FIXME: These bindings shouldn't be Go-specific and should eventually move to -// a (somewhat) less stable collection of C APIs for use in creating bindings of -// LLVM in other languages. - -void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM); -void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM); -void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM); -void LLVMAddMemorySanitizerLegacyPassPass(LLVMPassManagerRef PM); -void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, int ABIListFilesNum, - const char **ABIListFiles); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/llvm/bindings/go/llvm/InstrumentationBindings.cpp b/llvm/bindings/go/llvm/InstrumentationBindings.cpp deleted file mode 100644 --- a/llvm/bindings/go/llvm/InstrumentationBindings.cpp +++ /dev/null @@ -1,48 +0,0 @@ -//===- InstrumentationBindings.cpp - instrumentation bindings -------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines C bindings for the instrumentation component. -// -//===----------------------------------------------------------------------===// - -#include "InstrumentationBindings.h" -#include "llvm-c/Core.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/IR/Module.h" -#include "llvm/Transforms/Instrumentation.h" -#include "llvm/Transforms/Instrumentation/AddressSanitizer.h" -#include "llvm/Transforms/Instrumentation/MemorySanitizer.h" -#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" - -using namespace llvm; - -void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createAddressSanitizerFunctionPass()); -} - -void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createModuleAddressSanitizerLegacyPassPass()); -} - -void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createThreadSanitizerLegacyPassPass()); -} - -void LLVMAddMemorySanitizerLegacyPassPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createMemorySanitizerLegacyPassPass()); -} - -void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, - int ABIListFilesNum, - const char **ABIListFiles) { - std::vector ABIListFilesVec; - for (int i = 0; i != ABIListFilesNum; ++i) { - ABIListFilesVec.push_back(ABIListFiles[i]); - } - unwrap(PM)->add(createDataFlowSanitizerPass(ABIListFilesVec)); -} diff --git a/llvm/bindings/go/llvm/transforms_instrumentation.go b/llvm/bindings/go/llvm/transforms_instrumentation.go --- a/llvm/bindings/go/llvm/transforms_instrumentation.go +++ b/llvm/bindings/go/llvm/transforms_instrumentation.go @@ -13,18 +13,21 @@ package llvm /* -#include "InstrumentationBindings.h" +#include "IRBindings.h" +#include "llvm-c/Instrumentation.h" #include */ import "C" import "unsafe" func (pm PassManager) AddAddressSanitizerFunctionPass() { - C.LLVMAddAddressSanitizerFunctionPass(pm.C) + C.LLVMAddAddressSanitizerFunctionPass(pm.C, C.LLVMBool(0), + C.LLVMBool(0), C.LLVMBool(0)) } func (pm PassManager) AddAddressSanitizerModulePass() { - C.LLVMAddAddressSanitizerModulePass(pm.C) + C.LLVMAddAddressSanitizerModulePass(pm.C, C.LLVMBool(0), + C.LLVMBool(0), C.LLVMBool(0)) } func (pm PassManager) AddThreadSanitizerPass() { @@ -32,7 +35,7 @@ } func (pm PassManager) AddMemorySanitizerLegacyPassPass() { - C.LLVMAddMemorySanitizerLegacyPassPass(pm.C) + C.LLVMAddMemorySanitizerPass(pm.C, nil) } func (pm PassManager) AddDataFlowSanitizerPass(abilist []string) { @@ -41,5 +44,5 @@ abiliststrs[i] = C.CString(arg) defer C.free(unsafe.Pointer(abiliststrs[i])) } - C.LLVMAddDataFlowSanitizerPass(pm.C, C.int(len(abilist)), &abiliststrs[0]) + C.LLVMAddDataFlowSanitizerPass(pm.C, &abiliststrs[0], C.size_t(len(abilist)), nil, nil) } diff --git a/llvm/include/llvm-c/Instrumentation.h b/llvm/include/llvm-c/Instrumentation.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm-c/Instrumentation.h @@ -0,0 +1,131 @@ +/*===-- llvm-c/Instrumentation.h ---- Instrumentation Pass Bindings - C++ -*-=*\ +|* *| +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| +|* Exceptions. *| +|* See https://llvm.org/LICENSE.txt for license information. *| +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This header declares the C interface to the instrumentation passes defined +|* in libLLVMInstrumentation. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#ifndef LLVM_C_INSTRUMENTATION_H +#define LLVM_C_INSTRUMENTATION_H + +#include "llvm-c/DataTypes.h" +#include "llvm-c/Types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Creates and initializes options suitable for configuring the code coverage + * instrumentation passes. The caller is responsible for freeing this by calling + * \c LLVMDisposeSanitizerCoverageOptions. + * + * @see llvm::SanitizerCoverageOptions::SanitizerCoverageOptions() + */ +LLVMSanitizerCoverageOptions LLVMCreateSanitizerCoverageOptions( + unsigned CoverageType, + LLVMBool IndirectCalls, + LLVMBool TraceBB, + LLVMBool TraceCmp, + LLVMBool TraceDiv, + LLVMBool TraceGep, + LLVMBool Use8bitCounters, + LLVMBool TracePC, + LLVMBool TracePCGuard, + LLVMBool Inline8bitCounters, + LLVMBool PCTable, + LLVMBool NoPrune, + LLVMBool StackDepth); + +/** + * Destroys code coverage instrumentation options. + */ +void LLVMDisposeSanitizerCoverageOptions(LLVMSanitizerCoverageOptions Opts); + +/* @see llvm::createSanitizerCoverageModulePass */ +void LLVMAddSanitizerCoverageModulePass(LLVMPassManagerRef PM, + LLVMSanitizerCoverageOptions Options); + +/* @see llvm::createAddressSanitizerFunctionPass */ +void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM, + LLVMBool CompileKernel, + LLVMBool Recover, + LLVMBool UseAfterScope); + +/* @see llvm::createModuleAddressSanitizerLegacyPassPass */ +void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM, + LLVMBool CompileKernel, + LLVMBool Recover, + LLVMBool UseGlobalsGC); + +/* @see llvm::createHWAddressSanitizerPass */ +void LLVMAddHWAddressSanitizerPasses(LLVMPassManagerRef PM, + LLVMBool CompileKernel, + LLVMBool Recover); + +/** + * Creates and initializes options suitable for configuring the memory sanitizer + * instrumentation passes. The caller is responsible for freeing this by calling + * \c LLVMDisposeMemorySanitizerOptions. + * + * @see llvm::MemorySanitizerOptions::MemorySanitizerOptions() + */ +LLVMMemorySanitizerOptions LLVMCreateMemorySanitizerOptions(int TrackOrigins, + LLVMBool Recover, + LLVMBool Kernel); + +/** + * Destroys memory sanitizer instrumentation options. + */ +void LLVMDisposeMemorySanitizerOptions(LLVMMemorySanitizerOptions Opts); + +/* llvm::createMemorySanitizerLegacyPassPass */ +void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM, + LLVMMemorySanitizerOptions Options); + + +/* @see llvm::createThreadSanitizerLegacyPassPass */ +void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM); + + +/* @see llvm::createDataFlowSanitizerPass */ +void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, + char **ABIListFiles, + size_t ABIListFilesCount, + void *(*getArgTLS)(), + void *(*getRetValTLS)()); + + +/** + * Creates and initializes options suitable for configuring the efficiency + * sanitizer instrumentation passes. The caller is responsible for freeing this + * by calling \c LLVMDisposeEfficiencySanitizerOptions. + * + * @see llvm::LLVMEfficiencySanitizerOptions::LLVMEfficiencySanitizerOptions() + */ +LLVMEfficiencySanitizerOptions LLVMCreateEfficiencySanitizerOptions( + unsigned ToolType); + +/** + * Destroys efficiency sanitizer instrumentation options. + */ +void LLVMDisposeEfficiencySanitizerOptions(LLVMEfficiencySanitizerOptions Opts); + +/* @see llvm::createEfficiencySanitizerPass */ +void LLVMAddEfficiencySanitizerPass(LLVMPassManagerRef PM, + LLVMEfficiencySanitizerOptions Options); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/llvm/include/llvm-c/Types.h b/llvm/include/llvm-c/Types.h --- a/llvm/include/llvm-c/Types.h +++ b/llvm/include/llvm-c/Types.h @@ -163,6 +163,21 @@ */ typedef struct LLVMOpaqueJITEventListener *LLVMJITEventListenerRef; +/** + * @see llvm::SanitizerCoverageOptions + */ +typedef struct LLVMOpaqueSanitizerCoverageOptions *LLVMSanitizerCoverageOptions; + +/** + * @see llvm::MemorySanitizerOptions + */ +typedef struct LLVMOpaqueMemorySanitizerOptions *LLVMMemorySanitizerOptions; + +/** + * @see llvm::EfficiencySanitizerOptions + */ +typedef struct LLVMOpaqueEfficiencySanitizerOptions *LLVMEfficiencySanitizerOptions; + /** * @} */ diff --git a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp --- a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp +++ b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp @@ -13,16 +13,24 @@ #include "llvm/Transforms/Instrumentation.h" #include "llvm-c/Initialization.h" +#include "llvm-c/Transforms/Utils.h" #include "llvm/ADT/Triple.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" #include "llvm/PassRegistry.h" +#include "llvm/Support/CBindingWrapping.h" +#include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizer.h" +#include "llvm/Transforms/Instrumentation/MemorySanitizer.h" +#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" using namespace llvm; /// Moves I before IP. Returns new insert point. -static BasicBlock::iterator moveBeforeInsertPoint(BasicBlock::iterator I, BasicBlock::iterator IP) { +static BasicBlock::iterator moveBeforeInsertPoint(BasicBlock::iterator I, + BasicBlock::iterator IP) { // If I is IP, move the insert point down. if (I == IP) return ++IP; @@ -123,3 +131,156 @@ void LLVMInitializeInstrumentation(LLVMPassRegistryRef R) { initializeInstrumentation(*unwrap(R)); } + +struct LLVMOpaqueSanitizerCoverageOptions { + llvm::SanitizerCoverageOptions Opts; +}; + +LLVMSanitizerCoverageOptions LLVMCreateSanitizerCoverageOptions( + unsigned CoverageType, + LLVMBool IndirectCalls, + LLVMBool TraceBB, + LLVMBool TraceCmp, + LLVMBool TraceDiv, + LLVMBool TraceGep, + LLVMBool Use8bitCounters, + LLVMBool TracePC, + LLVMBool TracePCGuard, + LLVMBool Inline8bitCounters, + LLVMBool PCTable, + LLVMBool NoPrune, + LLVMBool StackDepth) { + SanitizerCoverageOptions Opts; + Opts.CoverageType = + static_cast(CoverageType); + Opts.IndirectCalls = IndirectCalls; + Opts.TraceBB = TraceBB; + Opts.TraceCmp = TraceCmp; + Opts.TraceDiv = TraceDiv; + Opts.TraceGep = TraceGep; + Opts.Use8bitCounters = Use8bitCounters; + Opts.TracePC = TracePC; + Opts.TracePCGuard = TracePCGuard; + Opts.NoPrune = NoPrune; + Opts.Inline8bitCounters = Inline8bitCounters; + Opts.PCTable = PCTable; + Opts.StackDepth = StackDepth; + LLVMOpaqueSanitizerCoverageOptions *Result = + static_cast( + safe_malloc(sizeof(LLVMOpaqueSanitizerCoverageOptions))); + Result->Opts = Opts; + return Result; +} + +void LLVMDisposeSanitizerCoverageOptions(LLVMSanitizerCoverageOptions Opts) { + free(Opts); +} + +void LLVMAddSanitizerCoverageModulePass(LLVMPassManagerRef PM, + LLVMSanitizerCoverageOptions Options) { + SanitizerCoverageOptions Opts; + if (Options) { + Opts = Options->Opts; + } + unwrap(PM)->add(createSanitizerCoverageModulePass(Opts)); +} + +void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM, + LLVMBool CompileKernel, + LLVMBool Recover, + LLVMBool UseAfterScope) { + unwrap(PM)->add(createAddressSanitizerFunctionPass(CompileKernel, + Recover, + UseAfterScope)); +} + +void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM, + LLVMBool CompileKernel, + LLVMBool Recover, + LLVMBool UseGlobalsGC) { + unwrap(PM)->add(createModuleAddressSanitizerLegacyPassPass(CompileKernel, + Recover, + UseGlobalsGC)); +} + +void LLVMAddHWAddressSanitizerPasses(LLVMPassManagerRef PM, + LLVMBool CompileKernel, + LLVMBool Recover) { + unwrap(PM)->add(createHWAddressSanitizerPass(CompileKernel, Recover)); +} + +struct LLVMOpaqueMemorySanitizerOptions { + llvm::MemorySanitizerOptions Opts; +}; + +LLVMMemorySanitizerOptions LLVMCreateMemorySanitizerOptions(int TrackOrigins, + LLVMBool Recover, + LLVMBool Kernel) { + MemorySanitizerOptions Opts; + Opts.TrackOrigins = TrackOrigins; + Opts.Recover = Recover; + Opts.Kernel = Kernel; + LLVMOpaqueMemorySanitizerOptions *Result = + static_cast( + safe_malloc(sizeof(LLVMOpaqueMemorySanitizerOptions))); + Result->Opts = Opts; + return Result; +} + +void LLVMDisposeMemorySanitizerOptions(LLVMMemorySanitizerOptions Opts) { + free(Opts); +} + +void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM, + LLVMMemorySanitizerOptions Options) { + MemorySanitizerOptions Opts; + if (Options) { + Opts = Options->Opts; + } + unwrap(PM)->add(createMemorySanitizerLegacyPassPass(Opts)); +} + +void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM) { + unwrap(PM)->add(createThreadSanitizerLegacyPassPass()); +} + +void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, + char **ABIListFiles, + size_t ABIListFilesCount, + void *(*getArgTLS)(), + void *(*getRetValTLS)()) { + std::vector ABIListFilesVec; + for (size_t i = 0; i != ABIListFilesCount; ++i) { + ABIListFilesVec.push_back(ABIListFiles[i]); + } + unwrap(PM)->add(createDataFlowSanitizerPass(ABIListFilesVec, + getArgTLS, getRetValTLS)); +} + +struct LLVMOpaqueEfficiencySanitizerOptions { + llvm::EfficiencySanitizerOptions Opts; +}; + +LLVMEfficiencySanitizerOptions LLVMCreateEfficiencySanitizerOptions( + unsigned ToolType) { + EfficiencySanitizerOptions Opts; + Opts.ToolType = static_cast(ToolType); + LLVMOpaqueEfficiencySanitizerOptions *Result = + static_cast( + safe_malloc(sizeof(LLVMOpaqueEfficiencySanitizerOptions))); + Result->Opts = Opts; + return Result; +} + +void LLVMDisposeEfficiencySanitizerOptions(LLVMEfficiencySanitizerOptions Opt) { + free(Opt); +} + +void LLVMAddEfficiencySanitizerPass(LLVMPassManagerRef PM, + LLVMEfficiencySanitizerOptions Options) { + EfficiencySanitizerOptions Opts; + if (Options) { + Opts = Options->Opts; + } + unwrap(PM)->add(createEfficiencySanitizerPass(Opts)); +}