From: Michael Lentine <mlent...@google.com>

This patch automtically adjusts the path of MMAP records
associated with Android system libraries. It enables running
perf reporting tools directly on the Android system natively.

Reviewed-by: Stephane Eranian <eran...@google.com>
Signed-off-by: Michael Lentine <mlent...@google.com>
---
 tools/perf/util/map.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 88 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index ba5f5c0c..1960883 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -32,6 +32,86 @@ 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) {
+                       snprintf(*newfilename, new_length + strlen(apk_path) + 
1,
+                                "%s/libs/%s/%s", apk_path, app_abi, libname);
+               } else {
+                       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);
+
+               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 +139,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 +156,12 @@ struct map *map__new(struct list_head *dsos__list, u64 
start, u64 len,
                        filename = newfilename;
                }
 
+               if (android) {
+                       char *newfilename_ptr = newfilename;
+                       if (replace_android_lib(filename, &newfilename_ptr))
+                               filename = newfilename;
+               }
+
                if (vdso) {
                        pgoff = 0;
                        dso = vdso__dso_findnew(dsos__list);
-- 
1.9.1.423.g4596e3a

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to