forked from OSchip/llvm-project
[sanitizer] Sanitizer __internal_*stat interface.
With this change, __internal_*stat always expect a "struct stat *" argument. This avoids stat/stat64 caller-side confusion (sanitizer_common tests already made this mistake), and allows the use of __internal_fstat() as a drop-in replacement for libc's fstat(). llvm-svn: 181311
This commit is contained in:
parent
c2565855ff
commit
517118e6b4
|
@ -108,11 +108,34 @@ uptr internal_write(fd_t fd, const void *buf, uptr count) {
|
|||
return res;
|
||||
}
|
||||
|
||||
#if !SANITIZER_LINUX_USES_64BIT_SYSCALLS
|
||||
static void stat64_to_stat(struct stat64 *in, struct stat *out) {
|
||||
internal_memset(out, 0, sizeof(*out));
|
||||
out->st_dev = in->st_dev;
|
||||
out->st_ino = in->st_ino;
|
||||
out->st_mode = in->st_mode;
|
||||
out->st_nlink = in->st_nlink;
|
||||
out->st_uid = in->st_uid;
|
||||
out->st_gid = in->st_gid;
|
||||
out->st_rdev = in->st_rdev;
|
||||
out->st_size = in->st_size;
|
||||
out->st_blksize = in->st_blksize;
|
||||
out->st_blocks = in->st_blocks;
|
||||
out->st_atime = in->st_atime;
|
||||
out->st_mtime = in->st_mtime;
|
||||
out->st_ctime = in->st_ctime;
|
||||
out->st_ino = in->st_ino;
|
||||
}
|
||||
#endif
|
||||
|
||||
int internal_stat(const char *path, void *buf) {
|
||||
#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
|
||||
return syscall(__NR_stat, path, buf);
|
||||
#else
|
||||
return syscall(__NR_stat64, path, buf);
|
||||
struct stat64 buf64;
|
||||
int res = syscall(__NR_stat64, path, &buf64);
|
||||
stat64_to_stat(&buf64, (struct stat *)buf);
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -120,7 +143,10 @@ int internal_lstat(const char *path, void *buf) {
|
|||
#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
|
||||
return syscall(__NR_lstat, path, buf);
|
||||
#else
|
||||
return syscall(__NR_lstat64, path, buf);
|
||||
struct stat64 buf64;
|
||||
int res = syscall(__NR_lstat64, path, &buf64);
|
||||
stat64_to_stat(&buf64, (struct stat *)buf);
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -128,16 +154,15 @@ int internal_fstat(fd_t fd, void *buf) {
|
|||
#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
|
||||
return syscall(__NR_fstat, fd, buf);
|
||||
#else
|
||||
return syscall(__NR_fstat64, fd, buf);
|
||||
struct stat64 buf64;
|
||||
int res = syscall(__NR_fstat64, fd, &buf64);
|
||||
stat64_to_stat(&buf64, (struct stat *)buf);
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
uptr internal_filesize(fd_t fd) {
|
||||
#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
|
||||
struct stat st;
|
||||
#else
|
||||
struct stat64 st;
|
||||
#endif
|
||||
if (internal_fstat(fd, &st))
|
||||
return -1;
|
||||
return (uptr)st.st_size;
|
||||
|
@ -166,15 +191,9 @@ void internal__exit(int exitcode) {
|
|||
|
||||
// ----------------- sanitizer_common.h
|
||||
bool FileExists(const char *filename) {
|
||||
#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
|
||||
struct stat st;
|
||||
if (syscall(__NR_stat, filename, &st))
|
||||
if (internal_stat(filename, &st))
|
||||
return false;
|
||||
#else
|
||||
struct stat64 st;
|
||||
if (syscall(__NR_stat64, filename, &st))
|
||||
return false;
|
||||
#endif
|
||||
// Sanity check: filename is a regular file.
|
||||
return S_ISREG(st.st_mode);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,11 @@ TEST(SanitizerCommon, mem_is_zero) {
|
|||
delete [] x;
|
||||
}
|
||||
|
||||
struct stat_and_more {
|
||||
struct stat st;
|
||||
unsigned char z;
|
||||
};
|
||||
|
||||
TEST(SanitizerCommon, FileOps) {
|
||||
const char *str1 = "qwerty";
|
||||
uptr len1 = internal_strlen(str1);
|
||||
|
@ -86,6 +91,15 @@ TEST(SanitizerCommon, FileOps) {
|
|||
EXPECT_EQ(0, internal_lstat(temp_filename, &st2));
|
||||
EXPECT_EQ(0, internal_fstat(fd, &st3));
|
||||
EXPECT_EQ(fsize, (uptr)st3.st_size);
|
||||
|
||||
// Verify that internal_fstat does not write beyond the end of the supplied
|
||||
// buffer.
|
||||
struct stat_and_more sam;
|
||||
memset(&sam, 0xAB, sizeof(sam));
|
||||
EXPECT_EQ(0, internal_fstat(fd, &sam.st));
|
||||
EXPECT_EQ(0xAB, sam.z);
|
||||
EXPECT_NE(0xAB, sam.st.st_size);
|
||||
EXPECT_NE(0, sam.st.st_size);
|
||||
#endif
|
||||
|
||||
char buf[64] = {};
|
||||
|
@ -97,3 +111,4 @@ TEST(SanitizerCommon, FileOps) {
|
|||
EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
|
||||
internal_close(fd);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue