blob: 26a08ae8f5b6bf4fd8ed3384266835270d21457d [file] [log] [blame]
Kostya Serebryany019b76f2011-11-30 01:07:02 +00001//===-- asan_linux.cc -----------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of AddressSanitizer, an address sanity checker.
11//
12// Linux-specific details.
13//===----------------------------------------------------------------------===//
Kostya Serebryany5dfa4da2011-12-01 21:40:52 +000014#ifdef __linux__
Kostya Serebryany019b76f2011-11-30 01:07:02 +000015
16#include "asan_internal.h"
17
18#include <sys/mman.h>
19#include <sys/syscall.h>
Kostya Serebryany6c4bd802011-12-28 22:58:01 +000020#include <sys/types.h>
21#include <fcntl.h>
Kostya Serebryany019b76f2011-11-30 01:07:02 +000022#include <unistd.h>
23
24extern char _DYNAMIC[];
25
26namespace __asan {
27
28void *AsanDoesNotSupportStaticLinkage() {
29 // This will fail to link with -static.
30 return &_DYNAMIC;
31}
32
Kostya Serebryanya7720962011-12-28 23:28:54 +000033static void *asan_mmap(void *addr, size_t length, int prot, int flags,
Kostya Serebryany019b76f2011-11-30 01:07:02 +000034 int fd, uint64_t offset) {
35# if __WORDSIZE == 64
Kostya Serebryany6c4bd802011-12-28 22:58:01 +000036 return (void *)syscall(__NR_mmap, addr, length, prot, flags, fd, offset);
Kostya Serebryany019b76f2011-11-30 01:07:02 +000037# else
Kostya Serebryany6c4bd802011-12-28 22:58:01 +000038 return (void *)syscall(__NR_mmap2, addr, length, prot, flags, fd, offset);
Kostya Serebryany019b76f2011-11-30 01:07:02 +000039# endif
40}
41
Kostya Serebryany6c4bd802011-12-28 22:58:01 +000042void *AsanMmapSomewhereOrDie(size_t size, const char *mem_type) {
43 size = RoundUpTo(size, kPageSize);
44 void *res = asan_mmap(0, size,
45 PROT_READ | PROT_WRITE,
46 MAP_PRIVATE | MAP_ANON, -1, 0);
47 if (res == (void*)-1) {
48 OutOfMemoryMessageAndDie(mem_type, size);
49 }
50 return res;
51}
52
Kostya Serebryanya7720962011-12-28 23:28:54 +000053void *AsanMmapFixedNoReserve(uintptr_t fixed_addr, size_t size) {
54 return asan_mmap((void*)fixed_addr, size,
55 PROT_READ | PROT_WRITE,
56 MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE,
57 0, 0);
58}
59
60void *AsanMmapFixedReserve(uintptr_t fixed_addr, size_t size) {
61 return asan_mmap((void*)fixed_addr, size,
62 PROT_READ | PROT_WRITE,
63 MAP_PRIVATE | MAP_ANON | MAP_FIXED,
64 0, 0);
65}
66
67void *AsanMprotect(uintptr_t fixed_addr, size_t size) {
68 return asan_mmap((void*)fixed_addr, size,
69 PROT_NONE,
70 MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE,
71 0, 0);
72}
73
Kostya Serebryany6c4bd802011-12-28 22:58:01 +000074void AsanUnmapOrDie(void *addr, size_t size) {
75 if (!addr || !size) return;
76 int res = syscall(__NR_munmap, addr, size);
77 if (res != 0) {
78 Report("Failed to unmap\n");
79 ASAN_DIE;
80 }
81}
82
83ssize_t AsanWrite(int fd, const void *buf, size_t count) {
84 return (ssize_t)syscall(__NR_write, fd, buf, count);
85}
86
87int AsanOpenReadonly(const char* filename) {
88 return open(filename, O_RDONLY);
89}
90
91ssize_t AsanRead(int fd, void *buf, size_t count) {
92 return (ssize_t)syscall(__NR_read, fd, buf, count);
93}
94
95int AsanClose(int fd) {
96 return close(fd);
Kostya Serebryany019b76f2011-11-30 01:07:02 +000097}
98
99} // namespace __asan
Kostya Serebryany5dfa4da2011-12-01 21:40:52 +0000100
101#endif // __linux__