Revert "[libFuzzer] Port to Windows"
This reverts r340949 due to bot breakage again. llvm-svn: 340954
This commit is contained in:
		
							parent
							
								
									8d8e1235ab
								
							
						
					
					
						commit
						cf311cfc20
					
				| 
						 | 
				
			
			@ -365,17 +365,6 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
 | 
			
		|||
    CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (TC.getSanitizerArgs().needsFuzzer()) {
 | 
			
		||||
    if (!Args.hasArg(options::OPT_shared))
 | 
			
		||||
      CmdArgs.push_back(
 | 
			
		||||
          Args.MakeArgString(std::string("-wholearchive:") +
 | 
			
		||||
                             TC.getCompilerRTArgString(Args, "fuzzer", false)));
 | 
			
		||||
    CmdArgs.push_back(Args.MakeArgString("-debug"));
 | 
			
		||||
    // Prevent the linker from padding sections we use for instrumentation
 | 
			
		||||
    // arrays.
 | 
			
		||||
    CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (TC.getSanitizerArgs().needsAsanRt()) {
 | 
			
		||||
    CmdArgs.push_back(Args.MakeArgString("-debug"));
 | 
			
		||||
    CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
 | 
			
		||||
| 
						 | 
				
			
			@ -1309,8 +1298,6 @@ MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
 | 
			
		|||
SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
 | 
			
		||||
  SanitizerMask Res = ToolChain::getSupportedSanitizers();
 | 
			
		||||
  Res |= SanitizerKind::Address;
 | 
			
		||||
  Res |= SanitizerKind::Fuzzer;
 | 
			
		||||
  Res |= SanitizerKind::FuzzerNoLink;
 | 
			
		||||
  Res &= ~SanitizerKind::CFIMFCall;
 | 
			
		||||
  return Res;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -619,7 +619,7 @@ else()
 | 
			
		|||
endif()
 | 
			
		||||
 | 
			
		||||
if (COMPILER_RT_HAS_SANITIZER_COMMON AND FUZZER_SUPPORTED_ARCH AND
 | 
			
		||||
    OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|FreeBSD|OpenBSD|Fuchsia|Windows")
 | 
			
		||||
    OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|FreeBSD|OpenBSD|Fuchsia")
 | 
			
		||||
  set(COMPILER_RT_HAS_FUZZER TRUE)
 | 
			
		||||
else()
 | 
			
		||||
  set(COMPILER_RT_HAS_FUZZER FALSE)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -129,15 +129,8 @@
 | 
			
		|||
 | 
			
		||||
#if LIBFUZZER_WINDOWS
 | 
			
		||||
#define ATTRIBUTE_INTERFACE __declspec(dllexport)
 | 
			
		||||
// This is used for __sancov_lowest_stack which is needed for
 | 
			
		||||
// -fsanitize-coverage=stack-depth. That feature is not yet available on
 | 
			
		||||
// Windows, so make the symbol static to avoid linking errors.
 | 
			
		||||
#define ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC \
 | 
			
		||||
  __attribute__((tls_model("initial-exec"))) thread_local static
 | 
			
		||||
#else
 | 
			
		||||
#define ATTRIBUTE_INTERFACE __attribute__((visibility("default")))
 | 
			
		||||
#define ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC \
 | 
			
		||||
  ATTRIBUTE_INTERFACE __attribute__((tls_model("initial-exec"))) thread_local
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace fuzzer {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,6 +100,14 @@ std::string DirPlusFile(const std::string &DirPath,
 | 
			
		|||
  return DirPath + GetSeparator() + FileName;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Basename(const std::string &Path, char Separator) {
 | 
			
		||||
  size_t Pos = Path.rfind(Separator);
 | 
			
		||||
  if (Pos == std::string::npos)
 | 
			
		||||
    return Path;
 | 
			
		||||
  assert(Pos < Path.size());
 | 
			
		||||
  return Path.substr(Pos + 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DupAndCloseStderr() {
 | 
			
		||||
  int OutputFd = DuplicateFile(2);
 | 
			
		||||
  if (OutputFd > 0) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,7 +68,7 @@ void GetSizedFilesFromDir(const std::string &Dir, Vector<SizedFile> *V);
 | 
			
		|||
 | 
			
		||||
char GetSeparator();
 | 
			
		||||
// Similar to the basename utility: returns the file name w/o the dir prefix.
 | 
			
		||||
std::string Basename(const std::string &Path);
 | 
			
		||||
std::string Basename(const std::string &Path, char Separator = GetSeparator());
 | 
			
		||||
 | 
			
		||||
FILE* OpenFile(int Fd, const char *Mode);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,13 +46,6 @@ size_t FileSize(const std::string &Path) {
 | 
			
		|||
  return St.st_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Basename(const std::string &Path) {
 | 
			
		||||
  size_t Pos = Path.rfind(GetSeparator());
 | 
			
		||||
  if (Pos == std::string::npos) return Path;
 | 
			
		||||
  assert(Pos < Path.size());
 | 
			
		||||
  return Path.substr(Pos + 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,
 | 
			
		||||
                             Vector<std::string> *V, bool TopDir) {
 | 
			
		||||
  auto E = GetEpoch(Dir);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,26 +72,6 @@ bool IsFile(const std::string &Path) {
 | 
			
		|||
  return IsFile(Path, Att);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Basename(const std::string &Path) {
 | 
			
		||||
  size_t Pos = Path.find_last_of("/\\");
 | 
			
		||||
  if (Pos == std::string::npos) return Path;
 | 
			
		||||
  assert(Pos < Path.size());
 | 
			
		||||
  return Path.substr(Pos + 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t FileSize(const std::string &Path) {
 | 
			
		||||
  WIN32_FILE_ATTRIBUTE_DATA attr;
 | 
			
		||||
  if (!GetFileAttributesExA(Path.c_str(), GetFileExInfoStandard, &attr)) {
 | 
			
		||||
    Printf("GetFileAttributesExA() failed for \"%s\" (Error code: %lu).\n",
 | 
			
		||||
           Path.c_str(), GetLastError());
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  ULARGE_INTEGER size;
 | 
			
		||||
  size.HighPart = attr.nFileSizeHigh;
 | 
			
		||||
  size.LowPart = attr.nFileSizeLow;
 | 
			
		||||
  return size.QuadPart;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,
 | 
			
		||||
                             Vector<std::string> *V, bool TopDir) {
 | 
			
		||||
  auto E = GetEpoch(Dir);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,8 @@ ATTRIBUTE_INTERFACE
 | 
			
		|||
uintptr_t __sancov_trace_pc_pcs[fuzzer::TracePC::kNumPCs];
 | 
			
		||||
 | 
			
		||||
// Used by -fsanitize-coverage=stack-depth to track stack depth
 | 
			
		||||
ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC uintptr_t __sancov_lowest_stack;
 | 
			
		||||
ATTRIBUTE_INTERFACE __attribute__((tls_model("initial-exec")))
 | 
			
		||||
thread_local uintptr_t __sancov_lowest_stack;
 | 
			
		||||
 | 
			
		||||
namespace fuzzer {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -179,9 +179,7 @@ const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
std::string DisassembleCmd(const std::string &FileName) {
 | 
			
		||||
  Vector<std::string> command_vector;
 | 
			
		||||
  command_vector.push_back("dumpbin /summary > nul");
 | 
			
		||||
  if (ExecuteCommand(Command(command_vector)) == 0)
 | 
			
		||||
  if (ExecuteCommand("dumpbin /summary > nul") == 0)
 | 
			
		||||
    return "dumpbin /disasm " + FileName;
 | 
			
		||||
  Printf("libFuzzer: couldn't find tool to disassemble (dumpbin)\n");
 | 
			
		||||
  exit(1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,8 +17,6 @@ list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS --driver-mode=g++)
 | 
			
		|||
 | 
			
		||||
if(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
 | 
			
		||||
  list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS -lc++ -lpthread)
 | 
			
		||||
elseif(WIN32)
 | 
			
		||||
  list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS -lstdc++)
 | 
			
		||||
else()
 | 
			
		||||
  list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS -lstdc++ -lpthread)
 | 
			
		||||
endif()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,13 +34,6 @@ TEST(Fuzzer, Basename) {
 | 
			
		|||
  EXPECT_EQ(Basename("/bar"), "bar");
 | 
			
		||||
  EXPECT_EQ(Basename("foo/x"), "x");
 | 
			
		||||
  EXPECT_EQ(Basename("foo/"), "");
 | 
			
		||||
#if LIBFUZZER_WINDOWS
 | 
			
		||||
  EXPECT_EQ(Basename("foo\\bar"), "bar");
 | 
			
		||||
  EXPECT_EQ(Basename("foo\\bar/baz"), "baz");
 | 
			
		||||
  EXPECT_EQ(Basename("\\bar"), "bar");
 | 
			
		||||
  EXPECT_EQ(Basename("foo\\x"), "x");
 | 
			
		||||
  EXPECT_EQ(Basename("foo\\"), "");
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(Fuzzer, CrossOver) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,57 +7,16 @@
 | 
			
		|||
//
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
//
 | 
			
		||||
// This file defines delimiters for Sanitizer Coverage's section. It contains
 | 
			
		||||
// Windows specific tricks to coax the linker into giving us the start and stop
 | 
			
		||||
// addresses of a section, as ELF linkers can do, to get the size of certain
 | 
			
		||||
// arrays. According to https://msdn.microsoft.com/en-us/library/7977wcck.aspx
 | 
			
		||||
// sections with the same name before "$" are sorted alphabetically by the
 | 
			
		||||
// string that comes after "$" and merged into one section. We take advantage
 | 
			
		||||
// of this by putting data we want the size of into the middle (M) of a section,
 | 
			
		||||
// by using the letter "M" after "$". We get the start of this data (ie:
 | 
			
		||||
// __start_section_name) by making the start variable come at the start of the
 | 
			
		||||
// section (using the letter A after "$"). We do the same to get the end of the
 | 
			
		||||
// data by using the letter "Z" after "$" to make the end variable come after
 | 
			
		||||
// the data. Note that because of our technique the address of the start
 | 
			
		||||
// variable is actually the address of data that comes before our middle
 | 
			
		||||
// section. We also need to prevent the linker from adding any padding. Each
 | 
			
		||||
// technique we use for this is explained in the comments below.
 | 
			
		||||
// This file defines delimiters for Sanitizer Coverage's section.
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
#include "sanitizer_platform.h"
 | 
			
		||||
#if SANITIZER_WINDOWS
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#pragma section(".SCOV$A", read, write)  // NOLINT
 | 
			
		||||
#pragma section(".SCOV$Z", read, write)  // NOLINT
 | 
			
		||||
extern "C" {
 | 
			
		||||
// The Guard array and counter array should both be merged into the .data
 | 
			
		||||
// section to reduce the number of PE sections However, because PCTable is
 | 
			
		||||
// constant it should be merged with the .rdata section.
 | 
			
		||||
#pragma section(".SCOV$GA", read, write)  // NOLINT
 | 
			
		||||
// Use align(1) to avoid adding any padding that will mess up clients trying to
 | 
			
		||||
// determine the start and end of the array.
 | 
			
		||||
__declspec(allocate(".SCOV$GA")) __declspec(align(1)) uint64_t
 | 
			
		||||
    __start___sancov_guards = 0;
 | 
			
		||||
#pragma section(".SCOV$GZ", read, write)  // NOLINT
 | 
			
		||||
__declspec(allocate(".SCOV$GZ")) __declspec(align(1)) uint64_t
 | 
			
		||||
    __stop___sancov_guards = 0;
 | 
			
		||||
 | 
			
		||||
#pragma section(".SCOV$CA", read, write)  // NOLINT
 | 
			
		||||
__declspec(allocate(".SCOV$CA")) __declspec(align(1)) uint64_t
 | 
			
		||||
    __start___sancov_cntrs = 0;
 | 
			
		||||
#pragma section(".SCOV$CZ", read, write)  // NOLINT
 | 
			
		||||
__declspec(allocate(".SCOV$CZ")) __declspec(align(1)) uint64_t
 | 
			
		||||
    __stop___sancov_cntrs = 0;
 | 
			
		||||
 | 
			
		||||
#pragma comment(linker, "/MERGE:.SCOV=.data")
 | 
			
		||||
 | 
			
		||||
// Use uint64_t so there won't be any issues if the linker tries to word align
 | 
			
		||||
// the pc array.
 | 
			
		||||
#pragma section(".SCOVP$A", read)  // NOLINT
 | 
			
		||||
__declspec(allocate(".SCOVP$A")) __declspec(align(1)) uint64_t
 | 
			
		||||
    __start___sancov_pcs = 0;
 | 
			
		||||
#pragma section(".SCOVP$Z", read)  // NOLINT
 | 
			
		||||
__declspec(allocate(".SCOVP$Z")) __declspec(align(1)) uint64_t
 | 
			
		||||
    __stop___sancov_pcs = 0;
 | 
			
		||||
 | 
			
		||||
#pragma comment(linker, "/MERGE:.SCOVP=.rdata")
 | 
			
		||||
__declspec(allocate(".SCOV$A")) uint32_t __start___sancov_guards = 0;
 | 
			
		||||
__declspec(allocate(".SCOV$Z")) uint32_t __stop___sancov_guards = 0;
 | 
			
		||||
}
 | 
			
		||||
#endif  // SANITIZER_WINDOWS
 | 
			
		||||
#endif // SANITIZER_WINDOWS
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,10 +62,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS)
 | 
			
		|||
    compiler_rt_test_runtime(sanitizer_common)
 | 
			
		||||
 | 
			
		||||
    # OpenBSD not supporting asan, cannot run the tests
 | 
			
		||||
    # Tests are broken for now on Windows
 | 
			
		||||
    if(COMPILER_RT_BUILD_LIBFUZZER
 | 
			
		||||
      AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD"
 | 
			
		||||
      AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows" AND NOT ANDROID)
 | 
			
		||||
    if(COMPILER_RT_BUILD_LIBFUZZER AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD" AND NOT ANDROID)
 | 
			
		||||
      compiler_rt_test_runtime(fuzzer)
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -273,20 +273,9 @@ Function *SanitizerCoverageModule::CreateInitCallsForSections(
 | 
			
		|||
  auto SecStart = SecStartEnd.first;
 | 
			
		||||
  auto SecEnd = SecStartEnd.second;
 | 
			
		||||
  Function *CtorFunc;
 | 
			
		||||
  Value *SecStartPtr = nullptr;
 | 
			
		||||
  // Account for the fact that on windows-msvc __start_* symbols actually
 | 
			
		||||
  // point to a uint64_t before the start of the array.
 | 
			
		||||
  if (TargetTriple.getObjectFormat() == Triple::COFF) {
 | 
			
		||||
    auto SecStartI8Ptr = IRB.CreatePointerCast(SecStart, Int8PtrTy);
 | 
			
		||||
    auto GEP = IRB.CreateGEP(SecStartI8Ptr,
 | 
			
		||||
                             ConstantInt::get(IntptrTy, sizeof(uint64_t)));
 | 
			
		||||
    SecStartPtr = IRB.CreatePointerCast(GEP, Ty);
 | 
			
		||||
  } else {
 | 
			
		||||
    SecStartPtr = IRB.CreatePointerCast(SecStart, Ty);
 | 
			
		||||
  }
 | 
			
		||||
  std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
 | 
			
		||||
      M, SanCovModuleCtorName, InitFunctionName, {Ty, Ty},
 | 
			
		||||
      {SecStartPtr, IRB.CreatePointerCast(SecEnd, Ty)});
 | 
			
		||||
      {IRB.CreatePointerCast(SecStart, Ty), IRB.CreatePointerCast(SecEnd, Ty)});
 | 
			
		||||
 | 
			
		||||
  if (TargetTriple.supportsCOMDAT()) {
 | 
			
		||||
    // Use comdat to dedup CtorFunc.
 | 
			
		||||
| 
						 | 
				
			
			@ -408,20 +397,9 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
 | 
			
		|||
    Function *InitFunction = declareSanitizerInitFunction(
 | 
			
		||||
        M, SanCovPCsInitName, {IntptrPtrTy, IntptrPtrTy});
 | 
			
		||||
    IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
 | 
			
		||||
    Value *SecStartPtr = nullptr;
 | 
			
		||||
    // Account for the fact that on windows-msvc __start_pc_table actually
 | 
			
		||||
    // points to a uint64_t before the start of the PC table.
 | 
			
		||||
    if (TargetTriple.getObjectFormat() == Triple::COFF) {
 | 
			
		||||
      auto SecStartI8Ptr = IRB.CreatePointerCast(SecStartEnd.first, Int8PtrTy);
 | 
			
		||||
      auto GEP = IRB.CreateGEP(SecStartI8Ptr,
 | 
			
		||||
                               ConstantInt::get(IntptrTy, sizeof(uint64_t)));
 | 
			
		||||
      SecStartPtr = IRB.CreatePointerCast(GEP, IntptrPtrTy);
 | 
			
		||||
    } else {
 | 
			
		||||
      SecStartPtr = IRB.CreatePointerCast(SecStartEnd.first, IntptrPtrTy);
 | 
			
		||||
    }
 | 
			
		||||
    IRBCtor.CreateCall(
 | 
			
		||||
        InitFunction,
 | 
			
		||||
        {SecStartPtr, IRB.CreatePointerCast(SecStartEnd.second, IntptrPtrTy)});
 | 
			
		||||
    IRBCtor.CreateCall(InitFunction,
 | 
			
		||||
                       {IRB.CreatePointerCast(SecStartEnd.first, IntptrPtrTy),
 | 
			
		||||
                        IRB.CreatePointerCast(SecStartEnd.second, IntptrPtrTy)});
 | 
			
		||||
  }
 | 
			
		||||
  // We don't reference these arrays directly in any of our runtime functions,
 | 
			
		||||
  // so we need to prevent them from being dead stripped.
 | 
			
		||||
| 
						 | 
				
			
			@ -831,13 +809,8 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
 | 
			
		|||
 | 
			
		||||
std::string
 | 
			
		||||
SanitizerCoverageModule::getSectionName(const std::string &Section) const {
 | 
			
		||||
  if (TargetTriple.getObjectFormat() == Triple::COFF) {
 | 
			
		||||
    if (Section == SanCovCountersSectionName)
 | 
			
		||||
      return ".SCOV$CM";
 | 
			
		||||
    if (Section == SanCovPCsSectionName)
 | 
			
		||||
      return ".SCOVP$M";
 | 
			
		||||
    return ".SCOV$GM"; // For SanCovGuardsSectionName.
 | 
			
		||||
  }
 | 
			
		||||
  if (TargetTriple.getObjectFormat() == Triple::COFF)
 | 
			
		||||
    return ".SCOV$M";
 | 
			
		||||
  if (TargetTriple.isOSBinFormatMachO())
 | 
			
		||||
    return "__DATA,__" + Section;
 | 
			
		||||
  return "__" + Section;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +0,0 @@
 | 
			
		|||
; Checks that the PC and 8-bit Counter Arrays are placed in their own sections in COFF binaries.
 | 
			
		||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
 | 
			
		||||
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
 | 
			
		||||
target triple = "x86_64-pc-windows-msvc19.14.26433"
 | 
			
		||||
 | 
			
		||||
define void @foo() {
 | 
			
		||||
entry:
 | 
			
		||||
  ret void
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
; CHECK-DAG: section ".SCOV{{\$}}CM",
 | 
			
		||||
; CHECK-DAG: section ".SCOVP{{\$}}M",
 | 
			
		||||
		Loading…
	
		Reference in New Issue