From patchwork Mon Jun 25 15:25:45 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernhard Rosenkraenzer X-Patchwork-Id: 9603 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 5890923F31 for ; Mon, 25 Jun 2012 15:25:49 +0000 (UTC) Received: from mail-gg0-f180.google.com (mail-gg0-f180.google.com [209.85.161.180]) by fiordland.canonical.com (Postfix) with ESMTP id 0683EA18358 for ; Mon, 25 Jun 2012 15:25:48 +0000 (UTC) Received: by ggnf1 with SMTP id f1so3167248ggn.11 for ; Mon, 25 Jun 2012 08:25:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :mime-version:date:message-id:subject:from:to:cc:content-type :x-gm-message-state; bh=iS0UYzmhRuB+84i+e2hpdItvx5ChJSgDPpdnlAIqZiU=; b=AER01nayp672aobCZ8dPB+jbDgyUk2zwrh364vyEGvg60xmizMPNjMY/ys6ifXr+c7 eq3w4tu6WOu7vYDysQAN60YkZAfh6F6yhurJOBd7thiqKOCvgNkIXw9O5U3Zgia0TGbK 77psLeyz7uJRR+UGafT3oe6BHMlzOp8bXOkUKHFsdwq69ac1LH9H2sOB/krWRBSqoKQ8 2R3NinPmA1OBW3ZwLgfIaOx/Lv1r3ASDp+Cgw1PdvkMABM+jtpkv0zj0Nds4+hzACguA eGFR6gVjsSmHiQtNc4LmTHbWDIgIpMQ869NsvhCZLd5OmSt5wnipwpC70YMd4hYvTudj JQHQ== Received: by 10.50.203.39 with SMTP id kn7mr8381970igc.53.1340637948191; Mon, 25 Jun 2012 08:25:48 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.24.148 with SMTP id v20csp50960ibb; Mon, 25 Jun 2012 08:25:46 -0700 (PDT) Received: by 10.220.228.193 with SMTP id jf1mr8247381vcb.73.1340637946437; Mon, 25 Jun 2012 08:25:46 -0700 (PDT) Received: from mail-vb0-f50.google.com (mail-vb0-f50.google.com [209.85.212.50]) by mx.google.com with ESMTPS id es5si6810190vdb.123.2012.06.25.08.25.45 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 25 Jun 2012 08:25:46 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.212.50 is neither permitted nor denied by best guess record for domain of bernhard.rosenkranzer@linaro.org) client-ip=209.85.212.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.212.50 is neither permitted nor denied by best guess record for domain of bernhard.rosenkranzer@linaro.org) smtp.mail=bernhard.rosenkranzer@linaro.org Received: by vbal1 with SMTP id l1so2735028vba.37 for ; Mon, 25 Jun 2012 08:25:45 -0700 (PDT) MIME-Version: 1.0 Received: by 10.52.99.227 with SMTP id et3mr6779410vdb.110.1340637945823; Mon, 25 Jun 2012 08:25:45 -0700 (PDT) Received: by 10.52.31.200 with HTTP; Mon, 25 Jun 2012 08:25:45 -0700 (PDT) Date: Mon, 25 Jun 2012 17:25:45 +0200 Message-ID: Subject: [PATCH] perf: Make perf buildable for Android From: =?ISO-8859-1?Q?Bernhard_Rosenkr=E4nzer?= To: linux-kernel@vger.kernel.org Cc: Patch Tracking X-Gm-Message-State: ALoCoQnAUz+ses4ulLt71lv1qYxmtdVh63oSE8bqMnrCpft/xIJeFG6bU09xw4EhFWcPb23YSw99 Hi, this patch allows compiling perf for Android (with Bionic instead of glibc). Nothing overly complicated in there, just a couple of workarounds for missing functionality and header oddities in Bionic. Signed-off-by: Bernhard Rosenkraenzer struct perf_evlist *other) @@ -339,6 +350,11 @@ static void perf_record__exit(int status __used, void *arg) symbol__exit(); } } +#ifdef ANDROID +static void perf_record__exit_android(void) { + perf_record__exit(0, __global_rec); +} +#endif static void perf_event__synthesize_guest_os(struct machine *machine, void *data) { @@ -412,7 +428,12 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) rec->page_size = sysconf(_SC_PAGE_SIZE); +#ifndef ANDROID on_exit(perf_record__sig_exit, rec); +#else + __global_rec = rec; + atexit(perf_record__sig_exit_android); +#endif signal(SIGCHLD, sig_handler); signal(SIGINT, sig_handler); signal(SIGUSR1, sig_handler); @@ -496,7 +517,11 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) /* * perf_session__delete(session) will be called at perf_record__exit() */ +#ifndef ANDROID on_exit(perf_record__exit, rec); +#else + atexit(perf_record__exit_android); +#endif if (opts->pipe_output) { err = perf_header__write_pipe(output); diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 92271d3..d15cdae 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -117,7 +117,7 @@ ifndef PERF_DEBUG endif CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -EXTLIBS = -lpthread -lrt -lelf -lm +EXTLIBS = -lpthread -lelf -lm ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE ALL_LDFLAGS = $(LDFLAGS) STRIP ?= strip @@ -474,12 +474,23 @@ FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y) FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS) ifneq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y) - msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static); + ifeq ($(call try-cc,$(SOURCE_BIONIC),$(FLAGS_GLIBC)),y) + # Found Bionic instead of glibc... + # That works too, but needs a bit of special treatment + BASIC_CFLAGS += -DANDROID -include compat-android.h + ANDROID := 1 + else + msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static); + endif else msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel); endif endif +ifneq ($(ANDROID),1) +EXTLIBS += -lrt +endif + ifneq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON)),y) BASIC_CFLAGS += -DLIBELF_NO_MMAP endif diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 223ffdc..1f20f4d 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c @@ -469,10 +469,17 @@ static int test__basic_mmap(void) .watermark = 0, }; cpu_set_t cpu_set; +#ifndef ANDROID const char *syscall_names[] = { "getsid", "getppid", "getpgrp", "getpgid", }; pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp, (void*)getpgid }; +#else + // No getsid() on Android + const char *syscall_names[] = { "getppid", "getpgrp", + "getpgid", }; + pid_t (*syscalls[])(void) = { getppid, getpgrp, (void*)getpgid }; +#endif #define nsyscalls ARRAY_SIZE(syscall_names) int ids[nsyscalls]; unsigned int nr_events[nsyscalls], diff --git a/tools/perf/compat-android.h b/tools/perf/compat-android.h new file mode 100644 index 0000000..7681f35 --- /dev/null +++ b/tools/perf/compat-android.h @@ -0,0 +1,90 @@ +/* Android compatibility header + * Provides missing bits in Bionic on Android, ignored + * on regular Linux. + * + * Written by Bernhard.Rosenkranzer@linaro.org + * + * Released into the public domain. Do with this file + * whatever you want. + */ +#ifdef ANDROID +/* Bionic has its own idea about ALIGN, and kills other definitions. + * Done outside the multiple-inclusion wrapper to make sure we + * can override Bionic's ALIGN by simply including compat-android.h + * again after including Bionic headers. + */ +#undef ALIGN +#undef __ALIGN_MASK +#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) +#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) + +#ifndef _COMPAT_ANDROID_H_ +#define _COMPAT_ANDROID_H_ 1 +#include +#include +#include // for PAGE_SIZE +#include // for winsize + +#ifndef __WORDSIZE +#include +#define __WORDSIZE _BITSIZE +#endif + +#ifndef roundup +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#endif + +#ifndef __force +#define __force +#endif + +// Assorted functions that are missing from Bionic +static void psignal(int sig, const char *s) { + if(sig>=0 && sig + +int main(void) +{ +#ifndef __ANDROID_API__ + error out +#else + return 0; +#endif +} +endef + define SOURCE_ELF_MMAP #include int main(void) diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index efa5dc8..ead88ea 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -6,6 +6,7 @@ #include "symbol.h" #include #include +#include struct objdump_line { struct list_head node; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2a6f33c..867415a 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -6,6 +6,7 @@ #include "strlist.h" #include "thread.h" #include "thread_map.h" +#include "../compat-android.h" static const char *perf_event__names[] = { [0] = "TOTAL", diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 1b19728..2b0554b 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -6,6 +6,7 @@ #include "../perf.h" #include "map.h" +#include "../compat-android.h" /* * PERF_SAMPLE_IP | PERF_SAMPLE_TID | * diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 0f99f39..77c5ced 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -70,15 +70,19 @@ #include #include #include +#ifndef ANDROID #include #include #include +#endif #include #include #include #include "../../../include/linux/magic.h" #include "types.h" +#ifndef ANDROID #include +#endif extern const char *graph_line; extern const char *graph_dotted_line; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 42e8aca..9eb8a4b 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -32,6 +32,12 @@ #include #include +#ifdef ANDROID +// While stdlib.h has a prototype for it, +// Bionic doesn't actually implement on_exit() +static struct perf_record *__global_rec; +#endif + enum write_mode_t { WRITE_FORCE, WRITE_APPEND @@ -156,6 +162,11 @@ static void perf_record__sig_exit(int exit_status __used, void *arg) signal(signr, SIG_DFL); kill(getpid(), signr); } +#ifdef ANDROID +static void perf_record__sig_exit_android(void) { + perf_record__sig_exit(0, __global_rec); +} +#endif static bool perf_evlist__equal(struct perf_evlist *evlist,