summaryrefslogtreecommitdiff
path: root/toolchain-extras
diff options
context:
space:
mode:
authorPirama Arumuga Nainar <pirama@google.com>2020-12-10 10:19:48 -0800
committerPirama Arumuga Nainar <pirama@google.com>2020-12-10 13:33:21 -0800
commit04195c55f3f12109f41d4130afe157046a0aa7a6 (patch)
tree768ab581af4c943718fa4bbdc8c085f9468068d3 /toolchain-extras
parent4c43577db1f6c4557d2b4a6fd9b1738cad667a41 (diff)
downloadextras-04195c55f3f12109f41d4130afe157046a0aa7a6.tar.gz
[coverage] Wrap calls to open
Bug: http://b/173448692 The coverage runtime creates files with uga+rw permissions but an earlier umask call can restrict these and cause problems with profile merging ('%Nm' in LLVM_PROFILE_FILE). This change adds a wrapper to `open` which will set the permissions again using `fchmod` for files opened under the /data/misc/trace directory. Test: Manually validate permissions of files under /data/misc/trace. Test: libprofile-clang-extras-test Change-Id: Iee7fe07b4bfb362fe5146c962b54affaa55ef380
Diffstat (limited to 'toolchain-extras')
-rw-r--r--toolchain-extras/Android.bp16
-rw-r--r--toolchain-extras/profile-clang-extras-test.cpp21
-rw-r--r--toolchain-extras/profile-clang-openat.cpp55
3 files changed, 91 insertions, 1 deletions
diff --git a/toolchain-extras/Android.bp b/toolchain-extras/Android.bp
index dec5d404..ff537a52 100644
--- a/toolchain-extras/Android.bp
+++ b/toolchain-extras/Android.bp
@@ -41,6 +41,7 @@ cc_defaults {
name: "libprofile-clang-defaults",
srcs: [
"profile-clang-extras.cpp",
+ "profile-clang-openat.cpp",
],
native_coverage: false,
}
@@ -86,3 +87,18 @@ cc_test {
ldflags: ["-uinit_profile_extras"],
native_coverage: false,
}
+
+cc_test {
+ name: "libprofile-clang-extras-test",
+ srcs: [
+ "profile-clang-extras-test.cpp",
+ ],
+ static_libs: [
+ "libprofile-clang-extras",
+ ],
+ ldflags: [
+ "-uinit_profile_extras",
+ "-Wl,--wrap,open",
+ ],
+ native_coverage: false,
+}
diff --git a/toolchain-extras/profile-clang-extras-test.cpp b/toolchain-extras/profile-clang-extras-test.cpp
index 2bb7bdbb..0c746478 100644
--- a/toolchain-extras/profile-clang-extras-test.cpp
+++ b/toolchain-extras/profile-clang-extras-test.cpp
@@ -14,7 +14,10 @@
* limitations under the License.
*/
+#include <fcntl.h>
#include <gtest/gtest.h>
+#include <sys/stat.h>
+
#include "profile-extras.h"
static int flush_count = 0;
@@ -30,7 +33,23 @@ TEST(profile_extras, smoke) {
flush_count = 0;
ASSERT_EQ(0, flush_count);
- kill(getpid(), GCOV_FLUSH_SIGNAL);
+ kill(getpid(), COVERAGE_FLUSH_SIGNAL);
sleep(2);
ASSERT_EQ(1, flush_count);
}
+
+static const char* OPEN_AT_TEST_FNAME = "/data/misc/trace/test.profraw";
+TEST(profile_extras, openat) {
+ mode_t old_umask = umask(0077);
+ unlink(OPEN_AT_TEST_FNAME);
+
+ int fd = open(OPEN_AT_TEST_FNAME, O_RDWR | O_CREAT, 0666);
+ ASSERT_NE(fd, -1);
+ close(fd);
+ umask(old_umask);
+
+ struct stat stat_buf;
+ ASSERT_EQ(stat(OPEN_AT_TEST_FNAME, &stat_buf), 0);
+ ASSERT_EQ(stat_buf.st_mode & 0777, 0666);
+ unlink(OPEN_AT_TEST_FNAME);
+}
diff --git a/toolchain-extras/profile-clang-openat.cpp b/toolchain-extras/profile-clang-openat.cpp
new file mode 100644
index 00000000..f2f43d14
--- /dev/null
+++ b/toolchain-extras/profile-clang-openat.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+// This file provides a wrapper for open.
+
+extern "C" {
+
+int __real_open(const char* pathname, int flags, ...);
+
+static bool needs_mode(int flags) {
+ return ((flags & O_CREAT) == O_CREAT) || ((flags & O_TMPFILE) == O_TMPFILE);
+}
+
+static const char* PROFRAW_START = "/data/misc/trace/";
+static bool is_coverage_trace(const char* pathname) {
+ if (strncmp(pathname, PROFRAW_START, strlen(PROFRAW_START)) == 0) return true;
+ return false;
+}
+
+__attribute__((weak)) int __wrap_open(const char* pathname, int flags, ...) {
+ if (!needs_mode(flags)) {
+ return __real_open(pathname, flags);
+ }
+
+ va_list args;
+ va_start(args, flags);
+ mode_t mode = static_cast<mode_t>(va_arg(args, int));
+ va_end(args);
+
+ int ret = __real_open(pathname, flags, mode);
+ if (is_coverage_trace(pathname)) fchmod(ret, mode);
+ return ret;
+}
+}