diff options
author | Michael Lentine <mlentine@google.com> | 2014-05-20 13:48:50 +0400 |
---|---|---|
committer | Jiri Olsa <jolsa@kernel.org> | 2014-05-21 17:03:25 +0400 |
commit | eca8183699964579ca8a0b8d116bd1f4da0136f7 (patch) | |
tree | 078bfe88e5c3fbe397c9ca0d4d8ab2e0ff63979d /tools | |
parent | 21cfc5e10395eba795c0610cf3cf7f0a4f6f33ff (diff) | |
download | linux-eca8183699964579ca8a0b8d116bd1f4da0136f7.tar.xz |
perf tools: Add automatic remapping of Android libraries
This patch automatically adjusts the path of MMAP records
associated with Android system libraries.
The Android system is organized with system libraries found in
/system/lib and user libraries in /data/app-lib. On the host system
(not running Android), system libraries can be found in the downloaded
NDK directory under ${NDK_ROOT}/platforms/${APP_PLATFORM}/arch-${ARCH}/usr/lib
and the user libraries are installed under libs/${APP_ABI} within
the apk build directory. This patch makes running the reporting
tools possible on the host system using the libraries from the NDK.
Signed-off-by: Michael Lentine <mlentine@google.com>
Reviewed-by: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1400579330-5043-3-git-send-email-eranian@google.com
[ fixed 'space required before the open parenthesis' checkpatch.pl errors ]
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/map.c | 95 |
1 files changed, 94 insertions, 1 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index ba5f5c0c838b..8ccbb32eda25 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -32,6 +32,93 @@ static inline int is_no_dso_memory(const char *filename) !strcmp(filename, "[heap]"); } +static inline int is_android_lib(const char *filename) +{ + return !strncmp(filename, "/data/app-lib", 13) || + !strncmp(filename, "/system/lib", 11); +} + +static inline bool replace_android_lib(const char *filename, char *newfilename) +{ + const char *libname; + char *app_abi; + size_t app_abi_length, new_length; + size_t lib_length = 0; + + libname = strrchr(filename, '/'); + if (libname) + lib_length = strlen(libname); + + app_abi = getenv("APP_ABI"); + if (!app_abi) + return false; + + app_abi_length = strlen(app_abi); + + if (!strncmp(filename, "/data/app-lib", 13)) { + char *apk_path; + + if (!app_abi_length) + return false; + + new_length = 7 + app_abi_length + lib_length; + + apk_path = getenv("APK_PATH"); + if (apk_path) { + new_length += strlen(apk_path) + 1; + if (new_length > PATH_MAX) + return false; + snprintf(newfilename, new_length, + "%s/libs/%s/%s", apk_path, app_abi, libname); + } else { + if (new_length > PATH_MAX) + return false; + snprintf(newfilename, new_length, + "libs/%s/%s", app_abi, libname); + } + return true; + } + + if (!strncmp(filename, "/system/lib/", 11)) { + char *ndk, *app; + const char *arch; + size_t ndk_length; + size_t app_length; + + ndk = getenv("NDK_ROOT"); + app = getenv("APP_PLATFORM"); + + if (!(ndk && app)) + return false; + + ndk_length = strlen(ndk); + app_length = strlen(app); + + if (!(ndk_length && app_length && app_abi_length)) + return false; + + arch = !strncmp(app_abi, "arm", 3) ? "arm" : + !strncmp(app_abi, "mips", 4) ? "mips" : + !strncmp(app_abi, "x86", 3) ? "x86" : NULL; + + if (!arch) + return false; + + new_length = 27 + ndk_length + + app_length + lib_length + + strlen(arch); + + if (new_length > PATH_MAX) + return false; + snprintf(newfilename, new_length, + "%s/platforms/%s/arch-%s/usr/lib/%s", + ndk, app, arch, libname); + + return true; + } + return false; +} + void map__init(struct map *map, enum map_type type, u64 start, u64 end, u64 pgoff, struct dso *dso) { @@ -59,8 +146,9 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, if (map != NULL) { char newfilename[PATH_MAX]; struct dso *dso; - int anon, no_dso, vdso; + int anon, no_dso, vdso, android; + android = is_android_lib(filename); anon = is_anon_memory(filename); vdso = is_vdso_map(filename); no_dso = is_no_dso_memory(filename); @@ -75,6 +163,11 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, filename = newfilename; } + if (android) { + if (replace_android_lib(filename, newfilename)) + filename = newfilename; + } + if (vdso) { pgoff = 0; dso = vdso__dso_findnew(dsos__list); |