aboutsummaryrefslogtreecommitdiff
path: root/contrib/compiler-rt/lib/cfi/cfi.cc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/compiler-rt/lib/cfi/cfi.cc')
-rw-r--r--contrib/compiler-rt/lib/cfi/cfi.cc40
1 files changed, 34 insertions, 6 deletions
diff --git a/contrib/compiler-rt/lib/cfi/cfi.cc b/contrib/compiler-rt/lib/cfi/cfi.cc
index a2f127f93cda..b0a943759678 100644
--- a/contrib/compiler-rt/lib/cfi/cfi.cc
+++ b/contrib/compiler-rt/lib/cfi/cfi.cc
@@ -13,15 +13,33 @@
#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_common.h"
#include "sanitizer_common/sanitizer_flag_parser.h"
#include "ubsan/ubsan_init.h"
#include "ubsan/ubsan_flags.h"
@@ -154,15 +172,25 @@ void ShadowBuilder::Add(uptr begin, uptr end, uptr cfi_check) {
*s = sv;
}
-#if SANITIZER_LINUX
+#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());
+ CHECK(res != MAP_FAILED);
+ ::memcpy(&shadow_, &main_shadow, GetShadowSize());
+#endif
} else {
// Initial setup.
CHECK_EQ(kCfiShadowLimitsStorageSize, GetPageSizeCached());
@@ -183,17 +211,17 @@ void ShadowBuilder::Install() {
// dlopen(RTLD_NOLOAD | RTLD_LAZY)
// dlsym("__cfi_check").
uptr find_cfi_check_in_dso(dl_phdr_info *info) {
- const ElfW(Dyn) *dynamic = nullptr;
+ 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 ElfW(Dyn) *)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
+ (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 ElfW(Dyn) *p = dynamic; p->d_tag != PT_NULL; ++p) {
+ 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)
@@ -227,7 +255,7 @@ uptr find_cfi_check_in_dso(dl_phdr_info *info) {
return 0;
}
- for (const ElfW(Sym) *p = (const ElfW(Sym) *)symtab; (ElfW(Addr))p < strtab;
+ 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.