[compiler-rt] r355144 - cfi: Rename source file from cc to cpp

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 28 14:03:42 PST 2019


Author: nico
Date: Thu Feb 28 14:03:41 2019
New Revision: 355144

URL: http://llvm.org/viewvc/llvm-project?rev=355144&view=rev
Log:
cfi: Rename source file from cc to cpp

See discussion on https://reviews.llvm.org/D58620 for the review.

Added:
    compiler-rt/trunk/lib/cfi/cfi.cpp
      - copied, changed from r355143, compiler-rt/trunk/lib/cfi/cfi.cc
Removed:
    compiler-rt/trunk/lib/cfi/cfi.cc
Modified:
    compiler-rt/trunk/lib/cfi/CMakeLists.txt

Modified: compiler-rt/trunk/lib/cfi/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/cfi/CMakeLists.txt?rev=355144&r1=355143&r2=355144&view=diff
==============================================================================
--- compiler-rt/trunk/lib/cfi/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/cfi/CMakeLists.txt Thu Feb 28 14:03:41 2019
@@ -1,7 +1,9 @@
 add_compiler_rt_component(cfi)
 
 if(OS_NAME MATCHES "Linux" OR OS_NAME MATCHES "FreeBSD" OR OS_NAME MATCHES "NetBSD")
-  set(CFI_SOURCES cfi.cc)
+  set(CFI_SOURCES
+    cfi.cpp
+    )
 
   include_directories(..)
 

Removed: compiler-rt/trunk/lib/cfi/cfi.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/cfi/cfi.cc?rev=355143&view=auto
==============================================================================
--- compiler-rt/trunk/lib/cfi/cfi.cc (original)
+++ compiler-rt/trunk/lib/cfi/cfi.cc (removed)
@@ -1,476 +0,0 @@
-//===-------- cfi.cc ------------------------------------------------------===//
-//
-// 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 implements the runtime support for the cross-DSO CFI.
-//
-//===----------------------------------------------------------------------===//
-
-#include <assert.h>
-#include <elf.h>
-
-#include "sanitizer_common/sanitizer_common.h"
-#if SANITIZER_FREEBSD
-#include <sys/link_elf.h>
-#endif
-#include <link.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-
-#if SANITIZER_LINUX
-typedef ElfW(Phdr) Elf_Phdr;
-typedef ElfW(Ehdr) Elf_Ehdr;
-typedef ElfW(Addr) Elf_Addr;
-typedef ElfW(Sym) Elf_Sym;
-typedef ElfW(Dyn) Elf_Dyn;
-#elif SANITIZER_FREEBSD
-#if SANITIZER_WORDSIZE == 64
-#define ElfW64_Dyn Elf_Dyn
-#define ElfW64_Sym Elf_Sym
-#else
-#define ElfW32_Dyn Elf_Dyn
-#define ElfW32_Sym Elf_Sym
-#endif
-#endif
-
-#include "interception/interception.h"
-#include "sanitizer_common/sanitizer_flag_parser.h"
-#include "ubsan/ubsan_init.h"
-#include "ubsan/ubsan_flags.h"
-
-#ifdef CFI_ENABLE_DIAG
-#include "ubsan/ubsan_handlers.h"
-#endif
-
-using namespace __sanitizer;
-
-namespace __cfi {
-
-#define kCfiShadowLimitsStorageSize 4096 // 1 page
-// Lets hope that the data segment is mapped with 4K pages.
-// The pointer to the cfi shadow region is stored at the start of this page.
-// The rest of the page is unused and re-mapped read-only.
-static union {
-  char space[kCfiShadowLimitsStorageSize];
-  struct {
-    uptr start;
-    uptr size;
-  } limits;
-} cfi_shadow_limits_storage
-    __attribute__((aligned(kCfiShadowLimitsStorageSize)));
-static constexpr uptr kShadowGranularity = 12;
-static constexpr uptr kShadowAlign = 1UL << kShadowGranularity; // 4096
-
-static constexpr uint16_t kInvalidShadow = 0;
-static constexpr uint16_t kUncheckedShadow = 0xFFFFU;
-
-// Get the start address of the CFI shadow region.
-uptr GetShadow() {
-  return cfi_shadow_limits_storage.limits.start;
-}
-
-uptr GetShadowSize() {
-  return cfi_shadow_limits_storage.limits.size;
-}
-
-// This will only work while the shadow is not allocated.
-void SetShadowSize(uptr size) {
-  cfi_shadow_limits_storage.limits.size = size;
-}
-
-uptr MemToShadowOffset(uptr x) {
-  return (x >> kShadowGranularity) << 1;
-}
-
-uint16_t *MemToShadow(uptr x, uptr shadow_base) {
-  return (uint16_t *)(shadow_base + MemToShadowOffset(x));
-}
-
-typedef int (*CFICheckFn)(u64, void *, void *);
-
-// This class reads and decodes the shadow contents.
-class ShadowValue {
-  uptr addr;
-  uint16_t v;
-  explicit ShadowValue(uptr addr, uint16_t v) : addr(addr), v(v) {}
-
-public:
-  bool is_invalid() const { return v == kInvalidShadow; }
-
-  bool is_unchecked() const { return v == kUncheckedShadow; }
-
-  CFICheckFn get_cfi_check() const {
-    assert(!is_invalid() && !is_unchecked());
-    uptr aligned_addr = addr & ~(kShadowAlign - 1);
-    uptr p = aligned_addr - (((uptr)v - 1) << kShadowGranularity);
-    return reinterpret_cast<CFICheckFn>(p);
-  }
-
-  // Load a shadow value for the given application memory address.
-  static const ShadowValue load(uptr addr) {
-    uptr shadow_base = GetShadow();
-    uptr shadow_offset = MemToShadowOffset(addr);
-    if (shadow_offset > GetShadowSize())
-      return ShadowValue(addr, kInvalidShadow);
-    else
-      return ShadowValue(
-          addr, *reinterpret_cast<uint16_t *>(shadow_base + shadow_offset));
-  }
-};
-
-class ShadowBuilder {
-  uptr shadow_;
-
-public:
-  // Allocate a new empty shadow (for the entire address space) on the side.
-  void Start();
-  // Mark the given address range as unchecked.
-  // This is used for uninstrumented libraries like libc.
-  // Any CFI check with a target in that range will pass.
-  void AddUnchecked(uptr begin, uptr end);
-  // Mark the given address range as belonging to a library with the given
-  // cfi_check function.
-  void Add(uptr begin, uptr end, uptr cfi_check);
-  // Finish shadow construction. Atomically switch the current active shadow
-  // region with the newly constructed one and deallocate the former.
-  void Install();
-};
-
-void ShadowBuilder::Start() {
-  shadow_ = (uptr)MmapNoReserveOrDie(GetShadowSize(), "CFI shadow");
-  VReport(1, "CFI: shadow at %zx .. %zx\n", shadow_, shadow_ + GetShadowSize());
-}
-
-void ShadowBuilder::AddUnchecked(uptr begin, uptr end) {
-  uint16_t *shadow_begin = MemToShadow(begin, shadow_);
-  uint16_t *shadow_end = MemToShadow(end - 1, shadow_) + 1;
-  // memset takes a byte, so our unchecked shadow value requires both bytes to
-  // be the same. Make sure we're ok during compilation.
-  static_assert((kUncheckedShadow & 0xff) == ((kUncheckedShadow >> 8) & 0xff),
-                "Both bytes of the 16-bit value must be the same!");
-  memset(shadow_begin, kUncheckedShadow & 0xff,
-         (shadow_end - shadow_begin) * sizeof(*shadow_begin));
-}
-
-void ShadowBuilder::Add(uptr begin, uptr end, uptr cfi_check) {
-  assert((cfi_check & (kShadowAlign - 1)) == 0);
-
-  // Don't fill anything below cfi_check. We can not represent those addresses
-  // in the shadow, and must make sure at codegen to place all valid call
-  // targets above cfi_check.
-  begin = Max(begin, cfi_check);
-  uint16_t *s = MemToShadow(begin, shadow_);
-  uint16_t *s_end = MemToShadow(end - 1, shadow_) + 1;
-  uint16_t sv = ((begin - cfi_check) >> kShadowGranularity) + 1;
-  for (; s < s_end; s++, sv++)
-    *s = sv;
-}
-
-#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
-void ShadowBuilder::Install() {
-  MprotectReadOnly(shadow_, GetShadowSize());
-  uptr main_shadow = GetShadow();
-  if (main_shadow) {
-    // Update.
-#if SANITIZER_LINUX
-    void *res = mremap((void *)shadow_, GetShadowSize(), GetShadowSize(),
-                       MREMAP_MAYMOVE | MREMAP_FIXED, (void *)main_shadow);
-    CHECK(res != MAP_FAILED);
-#elif SANITIZER_NETBSD
-    void *res = mremap((void *)shadow_, GetShadowSize(), (void *)main_shadow,
-                       GetShadowSize(), MAP_FIXED);
-    CHECK(res != MAP_FAILED);
-#else
-    void *res = MmapFixedOrDie(shadow_, GetShadowSize(), "cfi shadow");
-    CHECK(res != MAP_FAILED);
-    ::memcpy(&shadow_, &main_shadow, GetShadowSize());
-#endif
-  } else {
-    // Initial setup.
-    CHECK_EQ(kCfiShadowLimitsStorageSize, GetPageSizeCached());
-    CHECK_EQ(0, GetShadow());
-    cfi_shadow_limits_storage.limits.start = shadow_;
-    MprotectReadOnly((uptr)&cfi_shadow_limits_storage,
-                     sizeof(cfi_shadow_limits_storage));
-    CHECK_EQ(shadow_, GetShadow());
-  }
-}
-#else
-#error not implemented
-#endif
-
-// This is a workaround for a glibc bug:
-// https://sourceware.org/bugzilla/show_bug.cgi?id=15199
-// Other platforms can, hopefully, just do
-//    dlopen(RTLD_NOLOAD | RTLD_LAZY)
-//    dlsym("__cfi_check").
-uptr find_cfi_check_in_dso(dl_phdr_info *info) {
-  const Elf_Dyn *dynamic = nullptr;
-  for (int i = 0; i < info->dlpi_phnum; ++i) {
-    if (info->dlpi_phdr[i].p_type == PT_DYNAMIC) {
-      dynamic =
-          (const Elf_Dyn *)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
-      break;
-    }
-  }
-  if (!dynamic) return 0;
-  uptr strtab = 0, symtab = 0, strsz = 0;
-  for (const Elf_Dyn *p = dynamic; p->d_tag != PT_NULL; ++p) {
-    if (p->d_tag == DT_SYMTAB)
-      symtab = p->d_un.d_ptr;
-    else if (p->d_tag == DT_STRTAB)
-      strtab = p->d_un.d_ptr;
-    else if (p->d_tag == DT_STRSZ)
-      strsz = p->d_un.d_ptr;
-  }
-
-  if (symtab > strtab) {
-    VReport(1, "Can not handle: symtab > strtab (%p > %zx)\n", symtab, strtab);
-    return 0;
-  }
-
-  // Verify that strtab and symtab are inside of the same LOAD segment.
-  // This excludes VDSO, which has (very high) bogus strtab and symtab pointers.
-  int phdr_idx;
-  for (phdr_idx = 0; phdr_idx < info->dlpi_phnum; phdr_idx++) {
-    const Elf_Phdr *phdr = &info->dlpi_phdr[phdr_idx];
-    if (phdr->p_type == PT_LOAD) {
-      uptr beg = info->dlpi_addr + phdr->p_vaddr;
-      uptr end = beg + phdr->p_memsz;
-      if (strtab >= beg && strtab + strsz < end && symtab >= beg &&
-          symtab < end)
-        break;
-    }
-  }
-  if (phdr_idx == info->dlpi_phnum) {
-    // Nope, either different segments or just bogus pointers.
-    // Can not handle this.
-    VReport(1, "Can not handle: symtab %p, strtab %zx\n", symtab, strtab);
-    return 0;
-  }
-
-  for (const Elf_Sym *p = (const Elf_Sym *)symtab; (Elf_Addr)p < strtab;
-       ++p) {
-    // There is no reliable way to find the end of the symbol table. In
-    // lld-produces files, there are other sections between symtab and strtab.
-    // Stop looking when the symbol name is not inside strtab.
-    if (p->st_name >= strsz) break;
-    char *name = (char*)(strtab + p->st_name);
-    if (strcmp(name, "__cfi_check") == 0) {
-      assert(p->st_info == ELF32_ST_INFO(STB_GLOBAL, STT_FUNC) ||
-             p->st_info == ELF32_ST_INFO(STB_WEAK, STT_FUNC));
-      uptr addr = info->dlpi_addr + p->st_value;
-      return addr;
-    }
-  }
-  return 0;
-}
-
-int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *data) {
-  uptr cfi_check = find_cfi_check_in_dso(info);
-  if (cfi_check)
-    VReport(1, "Module '%s' __cfi_check %zx\n", info->dlpi_name, cfi_check);
-
-  ShadowBuilder *b = reinterpret_cast<ShadowBuilder *>(data);
-
-  for (int i = 0; i < info->dlpi_phnum; i++) {
-    const Elf_Phdr *phdr = &info->dlpi_phdr[i];
-    if (phdr->p_type == PT_LOAD) {
-      // Jump tables are in the executable segment.
-      // VTables are in the non-executable one.
-      // Need to fill shadow for both.
-      // FIXME: reject writable if vtables are in the r/o segment. Depend on
-      // PT_RELRO?
-      uptr cur_beg = info->dlpi_addr + phdr->p_vaddr;
-      uptr cur_end = cur_beg + phdr->p_memsz;
-      if (cfi_check) {
-        VReport(1, "   %zx .. %zx\n", cur_beg, cur_end);
-        b->Add(cur_beg, cur_end, cfi_check);
-      } else {
-        b->AddUnchecked(cur_beg, cur_end);
-      }
-    }
-  }
-  return 0;
-}
-
-// Init or update shadow for the current set of loaded libraries.
-void UpdateShadow() {
-  ShadowBuilder b;
-  b.Start();
-  dl_iterate_phdr(dl_iterate_phdr_cb, &b);
-  b.Install();
-}
-
-void InitShadow() {
-  CHECK_EQ(0, GetShadow());
-  CHECK_EQ(0, GetShadowSize());
-
-  uptr vma = GetMaxUserVirtualAddress();
-  // Shadow is 2 -> 2**kShadowGranularity.
-  SetShadowSize((vma >> (kShadowGranularity - 1)) + 1);
-  VReport(1, "CFI: VMA size %zx, shadow size %zx\n", vma, GetShadowSize());
-
-  UpdateShadow();
-}
-
-THREADLOCAL int in_loader;
-BlockingMutex shadow_update_lock(LINKER_INITIALIZED);
-
-void EnterLoader() {
-  if (in_loader == 0) {
-    shadow_update_lock.Lock();
-  }
-  ++in_loader;
-}
-
-void ExitLoader() {
-  CHECK(in_loader > 0);
-  --in_loader;
-  UpdateShadow();
-  if (in_loader == 0) {
-    shadow_update_lock.Unlock();
-  }
-}
-
-ALWAYS_INLINE void CfiSlowPathCommon(u64 CallSiteTypeId, void *Ptr,
-                                     void *DiagData) {
-  uptr Addr = (uptr)Ptr;
-  VReport(3, "__cfi_slowpath: %llx, %p\n", CallSiteTypeId, Ptr);
-  ShadowValue sv = ShadowValue::load(Addr);
-  if (sv.is_invalid()) {
-    VReport(1, "CFI: invalid memory region for a check target: %p\n", Ptr);
-#ifdef CFI_ENABLE_DIAG
-    if (DiagData) {
-      __ubsan_handle_cfi_check_fail(
-          reinterpret_cast<__ubsan::CFICheckFailData *>(DiagData), Addr, false);
-      return;
-    }
-#endif
-    Trap();
-  }
-  if (sv.is_unchecked()) {
-    VReport(2, "CFI: unchecked call (shadow=FFFF): %p\n", Ptr);
-    return;
-  }
-  CFICheckFn cfi_check = sv.get_cfi_check();
-  VReport(2, "__cfi_check at %p\n", cfi_check);
-  cfi_check(CallSiteTypeId, Ptr, DiagData);
-}
-
-void InitializeFlags() {
-  SetCommonFlagsDefaults();
-#ifdef CFI_ENABLE_DIAG
-  __ubsan::Flags *uf = __ubsan::flags();
-  uf->SetDefaults();
-#endif
-
-  FlagParser cfi_parser;
-  RegisterCommonFlags(&cfi_parser);
-  cfi_parser.ParseString(GetEnv("CFI_OPTIONS"));
-
-#ifdef CFI_ENABLE_DIAG
-  FlagParser ubsan_parser;
-  __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
-  RegisterCommonFlags(&ubsan_parser);
-
-  const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();
-  ubsan_parser.ParseString(ubsan_default_options);
-  ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
-#endif
-
-  InitializeCommonFlags();
-
-  if (Verbosity())
-    ReportUnrecognizedFlags();
-
-  if (common_flags()->help) {
-    cfi_parser.PrintFlagDescriptions();
-  }
-}
-
-} // namespace __cfi
-
-using namespace __cfi;
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
-__cfi_slowpath(u64 CallSiteTypeId, void *Ptr) {
-  CfiSlowPathCommon(CallSiteTypeId, Ptr, nullptr);
-}
-
-#ifdef CFI_ENABLE_DIAG
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
-__cfi_slowpath_diag(u64 CallSiteTypeId, void *Ptr, void *DiagData) {
-  CfiSlowPathCommon(CallSiteTypeId, Ptr, DiagData);
-}
-#endif
-
-static void EnsureInterceptorsInitialized();
-
-// Setup shadow for dlopen()ed libraries.
-// The actual shadow setup happens after dlopen() returns, which means that
-// a library can not be a target of any CFI checks while its constructors are
-// running. It's unclear how to fix this without some extra help from libc.
-// In glibc, mmap inside dlopen is not interceptable.
-// Maybe a seccomp-bpf filter?
-// We could insert a high-priority constructor into the library, but that would
-// not help with the uninstrumented libraries.
-INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
-  EnsureInterceptorsInitialized();
-  EnterLoader();
-  void *handle = REAL(dlopen)(filename, flag);
-  ExitLoader();
-  return handle;
-}
-
-INTERCEPTOR(int, dlclose, void *handle) {
-  EnsureInterceptorsInitialized();
-  EnterLoader();
-  int res = REAL(dlclose)(handle);
-  ExitLoader();
-  return res;
-}
-
-static BlockingMutex interceptor_init_lock(LINKER_INITIALIZED);
-static bool interceptors_inited = false;
-
-static void EnsureInterceptorsInitialized() {
-  BlockingMutexLock lock(&interceptor_init_lock);
-  if (interceptors_inited)
-    return;
-
-  INTERCEPT_FUNCTION(dlopen);
-  INTERCEPT_FUNCTION(dlclose);
-
-  interceptors_inited = true;
-}
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-#if !SANITIZER_CAN_USE_PREINIT_ARRAY
-// On ELF platforms, the constructor is invoked using .preinit_array (see below)
-__attribute__((constructor(0)))
-#endif
-void __cfi_init() {
-  SanitizerToolName = "CFI";
-  InitializeFlags();
-  InitShadow();
-
-#ifdef CFI_ENABLE_DIAG
-  __ubsan::InitAsPlugin();
-#endif
-}
-
-#if SANITIZER_CAN_USE_PREINIT_ARRAY
-// On ELF platforms, run cfi initialization before any other constructors.
-// On other platforms we use the constructor attribute to arrange to run our
-// initialization early.
-extern "C" {
-__attribute__((section(".preinit_array"),
-               used)) void (*__cfi_preinit)(void) = __cfi_init;
-}
-#endif

Copied: compiler-rt/trunk/lib/cfi/cfi.cpp (from r355143, compiler-rt/trunk/lib/cfi/cfi.cc)
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/cfi/cfi.cpp?p2=compiler-rt/trunk/lib/cfi/cfi.cpp&p1=compiler-rt/trunk/lib/cfi/cfi.cc&r1=355143&r2=355144&rev=355144&view=diff
==============================================================================
--- compiler-rt/trunk/lib/cfi/cfi.cc (original)
+++ compiler-rt/trunk/lib/cfi/cfi.cpp Thu Feb 28 14:03:41 2019
@@ -1,4 +1,4 @@
-//===-------- cfi.cc ------------------------------------------------------===//
+//===-------- cfi.cpp -----------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.




More information about the llvm-commits mailing list