summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinliang David Li <davidxl@google.com>2016-07-18 16:16:12 +0000
committerXinliang David Li <davidxl@google.com>2016-07-18 16:16:12 +0000
commit53e2f16931e10e7d32edd927739836169f80f2a5 (patch)
tree5c473b3fe651ded937d9b78a521e52c166a9112a
parent3e87a261cdc57c4d8f686161f9ecfff4bdacb6a3 (diff)
Code refactoring: extract path prefix handling code
.. into reusable interfaces. No functional change is expected. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@275807 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/profile/GCDAProfiling.c44
-rw-r--r--lib/profile/InstrProfilingInternal.h14
-rw-r--r--lib/profile/InstrProfilingUtil.c52
3 files changed, 74 insertions, 36 deletions
diff --git a/lib/profile/GCDAProfiling.c b/lib/profile/GCDAProfiling.c
index 51a40c5b6..2756084f5 100644
--- a/lib/profile/GCDAProfiling.c
+++ b/lib/profile/GCDAProfiling.c
@@ -20,8 +20,9 @@
|*
\*===----------------------------------------------------------------------===*/
-#include "InstrProfilingUtil.h"
+#include "InstrProfilingInternal.h"
#include "InstrProfilingPort.h"
+#include "InstrProfilingUtil.h"
#include <errno.h>
#include <fcntl.h>
@@ -171,45 +172,16 @@ static uint64_t read_64bit_value() {
static char *mangle_filename(const char *orig_filename) {
char *new_filename;
- size_t filename_len, prefix_len;
+ size_t prefix_len;
int prefix_strip;
- int level = 0;
- const char *fname, *ptr;
- const char *prefix = getenv("GCOV_PREFIX");
- const char *prefix_strip_str = getenv("GCOV_PREFIX_STRIP");
+ const char *prefix = lprofGetPathPrefix(&prefix_strip, &prefix_len);
- if (prefix == NULL || prefix[0] == '\0')
+ if (prefix == NULL)
return strdup(orig_filename);
- if (prefix_strip_str) {
- prefix_strip = atoi(prefix_strip_str);
-
- /* Negative GCOV_PREFIX_STRIP values are ignored */
- if (prefix_strip < 0)
- prefix_strip = 0;
- } else {
- prefix_strip = 0;
- }
-
- fname = orig_filename;
- for (level = 0, ptr = fname + 1; level < prefix_strip; ++ptr) {
- if (*ptr == '\0')
- break;
-
- if (!IS_DIR_SEPARATOR(*ptr))
- continue;
- fname = ptr;
- ++level;
- }
-
- filename_len = strlen(fname);
- prefix_len = strlen(prefix);
- new_filename = malloc(prefix_len + 1 + filename_len + 1);
- memcpy(new_filename, prefix, prefix_len);
-
- if (!IS_DIR_SEPARATOR(prefix[prefix_len - 1]))
- new_filename[prefix_len++] = DIR_SEPARATOR;
- memcpy(new_filename + prefix_len, fname, filename_len + 1);
+ new_filename = malloc(prefix_len + 1 + strlen(orig_filename) + 1);
+ lprofApplyPathPrefix(new_filename, orig_filename, prefix, prefix_len,
+ prefix_strip);
return new_filename;
}
diff --git a/lib/profile/InstrProfilingInternal.h b/lib/profile/InstrProfilingInternal.h
index bcbe29a03..44f308206 100644
--- a/lib/profile/InstrProfilingInternal.h
+++ b/lib/profile/InstrProfilingInternal.h
@@ -163,6 +163,20 @@ void lprofSetupValueProfiler();
* to dump merged profile data into its own profile file. */
uint64_t lprofGetLoadModuleSignature();
+/* GCOV_PREFIX and GCOV_PREFIX_STRIP support */
+/* Return the path prefix specified by GCOV_PREFIX environment variable.
+ * If GCOV_PREFIX_STRIP is also specified, the strip level (integer value)
+ * is returned via \c *PrefixStrip. The prefix length is stored in *PrefixLen.
+ */
+const char *lprofGetPathPrefix(int *PrefixStrip, size_t *PrefixLen);
+/* Apply the path prefix specified in \c Prefix to path string in \c PathStr,
+ * and store the result to buffer pointed to by \c Buffer. If \c PrefixStrip
+ * is not zero, path prefixes are stripped from \c PathStr (the level of
+ * stripping is specified by \c PrefixStrip) before \c Prefix is added.
+ */
+void lprofApplyPathPrefix(char *Dest, const char *PathStr, const char *Prefix,
+ size_t PrefixLen, int PrefixStrip);
+
COMPILER_RT_VISIBILITY extern char *(*GetEnvHook)(const char *);
COMPILER_RT_VISIBILITY extern void (*FreeHook)(void *);
COMPILER_RT_VISIBILITY extern uint8_t *DynamicBufferIOBuffer;
diff --git a/lib/profile/InstrProfilingUtil.c b/lib/profile/InstrProfilingUtil.c
index dc58d731b..5c66933bc 100644
--- a/lib/profile/InstrProfilingUtil.c
+++ b/lib/profile/InstrProfilingUtil.c
@@ -26,6 +26,7 @@
#include <sys/utsname.h>
#endif
+#include <stdlib.h>
#include <string.h>
COMPILER_RT_VISIBILITY
@@ -132,3 +133,54 @@ COMPILER_RT_VISIBILITY FILE *lprofOpenFileEx(const char *ProfileName) {
return f;
}
+
+COMPILER_RT_VISIBILITY const char *lprofGetPathPrefix(int *PrefixStrip,
+ size_t *PrefixLen) {
+ const char *Prefix = getenv("GCOV_PREFIX");
+ const char *PrefixStripStr = getenv("GCOV_PREFIX_STRIP");
+
+ *PrefixLen = 0;
+ *PrefixStrip = 0;
+ if (Prefix == NULL || Prefix[0] == '\0')
+ return NULL;
+
+ if (PrefixStripStr) {
+ *PrefixStrip = atoi(PrefixStripStr);
+
+ /* Negative GCOV_PREFIX_STRIP values are ignored */
+ if (*PrefixStrip < 0)
+ *PrefixStrip = 0;
+ } else {
+ *PrefixStrip = 0;
+ }
+ *PrefixLen = strlen(Prefix);
+
+ return Prefix;
+}
+
+COMPILER_RT_VISIBILITY void
+lprofApplyPathPrefix(char *Dest, const char *PathStr, const char *Prefix,
+ size_t PrefixLen, int PrefixStrip) {
+
+ const char *Ptr;
+ int Level;
+ const char *StrippedPathStr = PathStr;
+
+ for (Level = 0, Ptr = PathStr + 1; Level < PrefixStrip; ++Ptr) {
+ if (*Ptr == '\0')
+ break;
+
+ if (!IS_DIR_SEPARATOR(*Ptr))
+ continue;
+
+ StrippedPathStr = Ptr;
+ ++Level;
+ }
+
+ memcpy(Dest, Prefix, PrefixLen);
+
+ if (!IS_DIR_SEPARATOR(Prefix[PrefixLen - 1]))
+ Dest[PrefixLen++] = DIR_SEPARATOR;
+
+ memcpy(Dest + PrefixLen, StrippedPathStr, strlen(StrippedPathStr) + 1);
+}