diff options
| author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2014-12-24 12:58:09 +0000 |
|---|---|---|
| committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2014-12-24 12:58:09 +0000 |
| commit | 98211121abd4d68730372c873e5bbb41e2104fdb (patch) | |
| tree | 3feb95a91663d31b7976acdf33e78b00d564f619 | |
| parent | 0b7c1cf1e0268bf10c3a085e5604bff661f8d14d (diff) | |
| download | bcm5719-llvm-98211121abd4d68730372c873e5bbb41e2104fdb.tar.gz bcm5719-llvm-98211121abd4d68730372c873e5bbb41e2104fdb.zip | |
[sanitizer] mmap2 syscall works with 4096-byte units instead of bytes.
Ouch.
llvm-svn: 224819
| -rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_linux.cc | 8 | ||||
| -rw-r--r-- | compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc | 64 |
2 files changed, 51 insertions, 21 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc index 330fb98a3ec..1000a99d256 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc @@ -109,14 +109,16 @@ namespace __sanitizer { #endif // --------------- sanitizer_libc.h -uptr internal_mmap(void *addr, uptr length, int prot, int flags, - int fd, u64 offset) { +uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, + u64 offset) { #if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS return internal_syscall(SYSCALL(mmap), (uptr)addr, length, prot, flags, fd, offset); #else + // mmap2 specifies file offset in 4096-byte units. + CHECK(IsAligned(offset, 4096)); return internal_syscall(SYSCALL(mmap2), addr, length, prot, flags, fd, - offset); + offset / 4096); #endif } diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc index 660710d5bb7..a9e7fca7695 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc @@ -55,6 +55,19 @@ struct stat_and_more { unsigned char z; }; +static void temp_file_name(char *buf, size_t bufsize, const char *prefix) { + const char *tmpdir = "/tmp"; +#if SANITIZER_ANDROID + // I don't know a way to query temp directory location on Android without + // going through Java interfaces. The code below is not ideal, but should + // work. May require "adb root", but it is needed for almost any use of ASan + // on Android already. + tmpdir = GetEnv("EXTERNAL_STORAGE"); +#endif + u32 uid = GetUid(); + internal_snprintf(buf, bufsize, "%s/%s%d", tmpdir, prefix, uid); +} + // FIXME: File manipulations are not yet supported on Windows #if !defined(_WIN32) TEST(SanitizerCommon, FileOps) { @@ -63,28 +76,16 @@ TEST(SanitizerCommon, FileOps) { const char *str2 = "zxcv"; uptr len2 = internal_strlen(str2); - u32 uid = GetUid(); - char temp_filename[128]; -#if SANITIZER_ANDROID - // I don't know a way to query temp directory location on Android without - // going through Java interfaces. The code below is not ideal, but should - // work. May require "adb root", but it is needed for almost any use of ASan - // on Android already. - internal_snprintf(temp_filename, sizeof(temp_filename), - "%s/sanitizer_common.tmp.%d", - GetEnv("EXTERNAL_STORAGE"), uid); -#else - internal_snprintf(temp_filename, sizeof(temp_filename), - "/tmp/sanitizer_common.tmp.%d", uid); -#endif - uptr openrv = OpenFile(temp_filename, true); + char tmpfile[128]; + temp_file_name(tmpfile, sizeof(tmpfile), "sanitizer_common.fileops.tmp."); + uptr openrv = OpenFile(tmpfile, true); EXPECT_FALSE(internal_iserror(openrv)); fd_t fd = openrv; EXPECT_EQ(len1, internal_write(fd, str1, len1)); EXPECT_EQ(len2, internal_write(fd, str2, len2)); internal_close(fd); - openrv = OpenFile(temp_filename, false); + openrv = OpenFile(tmpfile, false); EXPECT_FALSE(internal_iserror(openrv)); fd = openrv; uptr fsize = internal_filesize(fd); @@ -92,8 +93,8 @@ TEST(SanitizerCommon, FileOps) { #if SANITIZER_TEST_HAS_STAT_H struct stat st1, st2, st3; - EXPECT_EQ(0u, internal_stat(temp_filename, &st1)); - EXPECT_EQ(0u, internal_lstat(temp_filename, &st2)); + EXPECT_EQ(0u, internal_stat(tmpfile, &st1)); + EXPECT_EQ(0u, internal_lstat(tmpfile, &st2)); EXPECT_EQ(0u, internal_fstat(fd, &st3)); EXPECT_EQ(fsize, (uptr)st3.st_size); @@ -115,6 +116,7 @@ TEST(SanitizerCommon, FileOps) { EXPECT_EQ(len2, internal_read(fd, buf, len2)); EXPECT_EQ(0, internal_memcmp(buf, str2, len2)); internal_close(fd); + internal_unlink(tmpfile); } #endif @@ -125,3 +127,29 @@ TEST(SanitizerCommon, InternalStrFunctions) { EXPECT_EQ(0, internal_strchr(haystack, 'z')); EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z')); } + +TEST(SanitizerCommon, InternalMmapWithOffset) { + char tmpfile[128]; + temp_file_name(tmpfile, sizeof(tmpfile), + "sanitizer_common.internalmmapwithoffset.tmp."); + uptr res = OpenFile(tmpfile, true); + ASSERT_FALSE(internal_iserror(res)); + fd_t fd = res; + + uptr page_size = GetPageSizeCached(); + res = internal_ftruncate(fd, page_size * 2); + ASSERT_FALSE(internal_iserror(res)); + + internal_lseek(fd, page_size, SEEK_SET); + internal_write(fd, "AB", 2); + + char *p = (char *)MapWritableFileToMemory(nullptr, page_size, fd, page_size); + ASSERT_NE(nullptr, p); + + ASSERT_EQ('A', p[0]); + ASSERT_EQ('B', p[1]); + + internal_close(fd); + internal_munmap(p, page_size); + internal_unlink(tmpfile); +} |

