142 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===- unittests/Driver/SanitizerArgsTest.cpp -----------------------------===//
 | |
| //
 | |
| // 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
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "clang/Basic/Diagnostic.h"
 | |
| #include "clang/Basic/DiagnosticIDs.h"
 | |
| #include "clang/Basic/DiagnosticOptions.h"
 | |
| #include "clang/Driver/Compilation.h"
 | |
| #include "clang/Driver/Driver.h"
 | |
| #include "clang/Driver/Job.h"
 | |
| #include "clang/Frontend/TextDiagnosticPrinter.h"
 | |
| #include "llvm/ADT/ArrayRef.h"
 | |
| #include "llvm/ADT/IntrusiveRefCntPtr.h"
 | |
| #include "llvm/ADT/Optional.h"
 | |
| #include "llvm/ADT/SmallString.h"
 | |
| #include "llvm/ADT/StringRef.h"
 | |
| #include "llvm/Support/Host.h"
 | |
| #include "llvm/Support/MemoryBuffer.h"
 | |
| #include "llvm/Support/Path.h"
 | |
| #include "llvm/Support/VirtualFileSystem.h"
 | |
| #include "llvm/Support/raw_ostream.h"
 | |
| #include "gmock/gmock.h"
 | |
| #include "gtest/gtest.h"
 | |
| #include <cstdlib>
 | |
| #include <memory>
 | |
| #include <string>
 | |
| using namespace clang;
 | |
| using namespace clang::driver;
 | |
| 
 | |
| using ::testing::Contains;
 | |
| using ::testing::StrEq;
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| static constexpr const char *ClangBinary = "clang";
 | |
| static constexpr const char *InputFile = "/sources/foo.c";
 | |
| 
 | |
| std::string concatPaths(llvm::ArrayRef<StringRef> Components) {
 | |
|   llvm::SmallString<128> P;
 | |
|   for (StringRef C : Components)
 | |
|     llvm::sys::path::append(P, C);
 | |
|   return std::string(P);
 | |
| }
 | |
| 
 | |
| class SanitizerArgsTest : public ::testing::Test {
 | |
| protected:
 | |
|   const Command &emulateSingleCompilation(std::vector<std::string> ExtraArgs,
 | |
|                                           std::vector<std::string> ExtraFiles) {
 | |
|     assert(!DriverInstance && "Running twice is not allowed");
 | |
| 
 | |
|     llvm::IntrusiveRefCntPtr<DiagnosticOptions> Opts = new DiagnosticOptions;
 | |
|     DiagnosticsEngine Diags(
 | |
|         new DiagnosticIDs, Opts,
 | |
|         new TextDiagnosticPrinter(llvm::errs(), Opts.get()));
 | |
|     DriverInstance.emplace(ClangBinary, "x86_64-unknown-linux-gnu", Diags,
 | |
|                            "clang LLVM compiler", prepareFS(ExtraFiles));
 | |
| 
 | |
|     std::vector<const char *> Args = {ClangBinary};
 | |
|     for (const auto &A : ExtraArgs)
 | |
|       Args.push_back(A.c_str());
 | |
|     Args.push_back("-c");
 | |
|     Args.push_back(InputFile);
 | |
| 
 | |
|     CompilationJob.reset(DriverInstance->BuildCompilation(Args));
 | |
| 
 | |
|     if (Diags.hasErrorOccurred())
 | |
|       ADD_FAILURE() << "Error occurred while parsing compilation arguments. "
 | |
|                        "See stderr for details.";
 | |
| 
 | |
|     const auto &Commands = CompilationJob->getJobs().getJobs();
 | |
|     assert(Commands.size() == 1);
 | |
|     return *Commands.front();
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem>
 | |
|   prepareFS(llvm::ArrayRef<std::string> ExtraFiles) {
 | |
|     llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS =
 | |
|         new llvm::vfs::InMemoryFileSystem;
 | |
|     FS->addFile(ClangBinary, time_t(), llvm::MemoryBuffer::getMemBuffer(""));
 | |
|     FS->addFile(InputFile, time_t(), llvm::MemoryBuffer::getMemBuffer(""));
 | |
|     for (llvm::StringRef F : ExtraFiles)
 | |
|       FS->addFile(F, time_t(), llvm::MemoryBuffer::getMemBuffer(""));
 | |
|     return FS;
 | |
|   }
 | |
| 
 | |
|   llvm::Optional<Driver> DriverInstance;
 | |
|   std::unique_ptr<driver::Compilation> CompilationJob;
 | |
| };
 | |
| 
 | |
| TEST_F(SanitizerArgsTest, Blacklists) {
 | |
|   const std::string ResourceDir = "/opt/llvm/lib/resources";
 | |
|   const std::string UserBlacklist = "/source/my_blacklist.txt";
 | |
|   const std::string ASanBlacklist =
 | |
|       concatPaths({ResourceDir, "share", "asan_blacklist.txt"});
 | |
| 
 | |
|   auto &Command = emulateSingleCompilation(
 | |
|       /*ExtraArgs=*/{"-fsanitize=address", "-resource-dir", ResourceDir,
 | |
|                      std::string("-fsanitize-blacklist=") + UserBlacklist},
 | |
|       /*ExtraFiles=*/{ASanBlacklist, UserBlacklist});
 | |
| 
 | |
|   // System blacklists are added based on resource-dir.
 | |
|   EXPECT_THAT(Command.getArguments(),
 | |
|               Contains(StrEq(std::string("-fsanitize-system-blacklist=") +
 | |
|                              ASanBlacklist)));
 | |
|   // User blacklists should also be added.
 | |
|   EXPECT_THAT(
 | |
|       Command.getArguments(),
 | |
|       Contains(StrEq(std::string("-fsanitize-blacklist=") + UserBlacklist)));
 | |
| }
 | |
| 
 | |
| TEST_F(SanitizerArgsTest, XRayLists) {
 | |
|   const std::string XRayWhitelist = "/source/xray_whitelist.txt";
 | |
|   const std::string XRayBlacklist = "/source/xray_blacklist.txt";
 | |
|   const std::string XRayAttrList = "/source/xray_attr_list.txt";
 | |
| 
 | |
|   auto &Command = emulateSingleCompilation(
 | |
|       /*ExtraArgs=*/
 | |
|       {
 | |
|           "-fxray-instrument",
 | |
|           "-fxray-always-instrument=" + XRayWhitelist,
 | |
|           "-fxray-never-instrument=" + XRayBlacklist,
 | |
|           "-fxray-attr-list=" + XRayAttrList,
 | |
|       },
 | |
|       /*ExtraFiles=*/{XRayWhitelist, XRayBlacklist, XRayAttrList});
 | |
| 
 | |
|   // Blacklists exist in the filesystem, so they should be added to the
 | |
|   // compilation command, produced by the driver.
 | |
|   EXPECT_THAT(Command.getArguments(),
 | |
|               Contains(StrEq("-fxray-always-instrument=" + XRayWhitelist)));
 | |
|   EXPECT_THAT(Command.getArguments(),
 | |
|               Contains(StrEq("-fxray-never-instrument=" + XRayBlacklist)));
 | |
|   EXPECT_THAT(Command.getArguments(),
 | |
|               Contains(StrEq("-fxray-attr-list=" + XRayAttrList)));
 | |
| }
 | |
| 
 | |
| } // namespace
 |