Compile oprofile tools on the host.

Some of the new build targets are disabled for now because libbfd is
not currently provided by the prebuilt toolchain for all platforms.

Change-Id: Ie2c24bf997c9c5f15f6c3e2eaf949d73578890d8
diff --git a/config.h b/config.h
index c220da5..96f3f22 100644
--- a/config.h
+++ b/config.h
@@ -50,10 +50,10 @@
 #define HAVE_UNISTD_H 1
 
 /* Define to 1 if you have the `xcalloc' function. */
-#undef HAVE_XCALLOC
+/* #undef HAVE_XCALLOC */
 
 /* Define to 1 if you have the `xmemdup' function. */
-#undef HAVE_XMEMDUP
+/* #undef HAVE_XMEMDUP */
 
 /* whether malloc attribute is understood */
 #define MALLOC_ATTRIBUTE_OK 1
diff --git a/libabi/Android.mk b/libabi/Android.mk
index 3213c1e..4f576ee 100644
--- a/libabi/Android.mk
+++ b/libabi/Android.mk
@@ -1,14 +1,51 @@
 LOCAL_PATH:= $(call my-dir)
+
+libabi_common_src := \
+	op_abi.c
+
+common_includes := \
+	external/oprofile \
+	external/oprofile/libdb \
+	external/oprofile/libutil \
+	external/oprofile/libop \
+	external/oprofile/libopt++
+
+# Build libabi on target
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= op_abi.c
-
+LOCAL_SRC_FILES:= $(libabi_common_src)
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libabi
 
-LOCAL_C_INCLUDES := \
-	$(LOCAL_PATH)/.. \
-	$(LOCAL_PATH)/../libdb \
-	$(LOCAL_PATH)/../libutil \
-	$(LOCAL_PATH)/../libop
-
 include $(BUILD_STATIC_LIBRARY)
+
+
+# Build libabi on host
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	$(libabi_common_src) \
+	abi.cpp
+
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_CFLAGS := -fexceptions -DANDROID_HOST
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libabi
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# Build opimport on host
+ifeq ($(HAVE_LIBBFD),true)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= opimport.cpp
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_CFLAGS := -fexceptions -DANDROID_HOST
+LOCAL_STATIC_LIBRARIES := libabi libdb libopt++ libutil libutil++ libpopt
+LOCAL_LDLIBS := -liberty
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := opimport
+
+include $(BUILD_HOST_EXECUTABLE)
+endif
diff --git a/libabi/opimport.cpp b/libabi/opimport.cpp
index 57f74a7..77d869e 100644
--- a/libabi/opimport.cpp
+++ b/libabi/opimport.cpp
@@ -114,6 +114,8 @@
 	extractor ext(abi, src, len);	
 
 	memcpy(head->magic, src + abi.need("offsetof_header_magic"), 4);
+	if (verbose)
+		cerr << hex << "magic = " << (int) head->magic[0] << ":" << (int) head->magic[1] << ":" << (int) head->magic[2] << ":" << (int) head->magic[3] << endl;
 
 	// begin extracting opd header
 	ext.extract(head->version, src, "sizeof_u32", "offsetof_header_version");
@@ -200,10 +202,12 @@
 	odb_t dest;
 	int rc;
 
-	assert((in_fd = open(inputs[0].c_str(), O_RDONLY)) > 0);		
-	assert(fstat(in_fd, &statb) == 0);
-	assert((in = mmap(0, statb.st_size, PROT_READ,
-			  MAP_PRIVATE, in_fd, 0)) != (void *)-1);
+	in_fd = open(inputs[0].c_str(), O_RDONLY);
+	assert(in_fd > 0);
+	rc = fstat(in_fd, &statb);
+	assert(rc == 0);
+	in = mmap(0, statb.st_size, PROT_READ, MAP_PRIVATE, in_fd, 0);
+	assert(in != (void *)-1);
 
 	rc = odb_open(&dest, output_filename.c_str(), ODB_RDWR,
 		      sizeof(struct opd_header));
@@ -221,5 +225,6 @@
 
 	odb_close(&dest);
 
-	assert(munmap(in, statb.st_size) == 0);
+	rc = munmap(in, statb.st_size);
+	assert(rc == 0);
 }
diff --git a/libdb/Android.mk b/libdb/Android.mk
index 1594fe8..fe359da 100644
--- a/libdb/Android.mk
+++ b/libdb/Android.mk
@@ -1,17 +1,38 @@
 LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
+common_src := \
 	db_debug.c \
 	db_insert.c \
 	db_manage.c \
 	db_stat.c \
 	db_travel.c
 
-LOCAL_C_INCLUDES := \
-	$(LOCAL_PATH)/.. \
-	$(LOCAL_PATH)/../libutil
+common_includes := \
+	external/oprofile \
+	external/oprofile/libutil
 
+# Build libdb on target
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(common_src)
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libdb
 
 include $(BUILD_STATIC_LIBRARY)
+
+# Build libdb on host
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(common_src)
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_CFLAGS := -fexceptions -DANDROID_HOST
+
+ifneq ($(HOST_OS),linux)
+LOCAL_CFLAGS += -DMISSING_MREMAP
+endif
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libdb
+
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/libdb/db_manage.c b/libdb/db_manage.c
index 17a0be5..5fc6fe9 100644
--- a/libdb/db_manage.c
+++ b/libdb/db_manage.c
@@ -77,12 +77,21 @@
 	if (ftruncate(data->fd, new_file_size))
 		return 1;
 
+#ifdef MISSING_MREMAP
+	new_map = mmap(0, new_file_size, PROT_READ | PROT_WRITE,
+		MAP_SHARED, data->fd, 0);
+#else
 	new_map = mremap(data->base_memory,
 			 old_file_size, new_file_size, MREMAP_MAYMOVE);
+#endif
 
 	if (new_map == MAP_FAILED)
 		return 1;
 
+#ifdef MISSING_MREMAP
+	munmap(data->base_memory, old_file_size);
+#endif
+
 	data->base_memory = new_map;
 	data->descr = odb_to_descr(data);
 	data->descr->size *= 2;
diff --git a/libop/Android.mk b/libop/Android.mk
index e935a45..01ddea9 100644
--- a/libop/Android.mk
+++ b/libop/Android.mk
@@ -1,7 +1,6 @@
 LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
+common_src := \
 	op_alloc_counter.c \
 	op_config.c \
 	op_cpu_type.c \
@@ -12,10 +11,29 @@
 	op_xml_events.c \
 	op_xml_out.c
 
-LOCAL_C_INCLUDES := \
-	$(LOCAL_PATH)/.. \
-	$(LOCAL_PATH)/../libutil
+common_includes := \
+	external/oprofile \
+	external/oprofile/libutil
 
+# Build libop on target
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(common_src)
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_CFLAGS := -fexceptions -DANDROID_HOST
+LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libop
 
 include $(BUILD_STATIC_LIBRARY)
+
+# Build libop on host
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(common_src)
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_CFLAGS := -DANDROID_HOST
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libop
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
diff --git a/libop/op_config.h b/libop/op_config.h
index 12e4b96..f8b56c4 100644
--- a/libop/op_config.h
+++ b/libop/op_config.h
@@ -25,7 +25,7 @@
  */
 void init_op_config_dirs(char const * session_dir);
 
-#ifndef ANDROID
+#if !defined(ANDROID) || defined(ANDROID_HOST)
 #define OP_SESSION_DIR_DEFAULT "/var/lib/oprofile/"
 #endif
 
diff --git a/libop/op_hw_specific.h b/libop/op_hw_specific.h
index 27c44ec..57d8149 100644
--- a/libop/op_hw_specific.h
+++ b/libop/op_hw_specific.h
@@ -5,7 +5,7 @@
  * @author Andi Kleen
  */
 
-#if defined(__i386__) || defined(__x86_64__) 
+#if (defined(__i386__) || defined(__x86_64__)) && !defined(ANDROID_HOST)
 
 /* Assume we run on the same host as the profilee */
 
diff --git a/libopt++/Android.mk b/libopt++/Android.mk
new file mode 100644
index 0000000..5901ef2
--- /dev/null
+++ b/libopt++/Android.mk
@@ -0,0 +1,15 @@
+LOCAL_PATH:= $(call my-dir)
+
+# Build libopt++ on host
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= popt_options.cpp
+LOCAL_C_INCLUDES := \
+	$(LOCAL_PATH)/.. \
+	$(LOCAL_PATH)/../libutil \
+	$(LOCAL_PATH)/../libutil++
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libopt++
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
diff --git a/libpopt/Android.mk b/libpopt/Android.mk
index b20cf55..4d513e8 100644
--- a/libpopt/Android.mk
+++ b/libpopt/Android.mk
@@ -1,15 +1,29 @@
 LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
+common_src := \
 	findme.c \
 	popt.c \
 	poptconfig.c \
 	popthelp.c \
 	poptparse.c
 
-LOCAL_CFLAGS += -DHAVE_CONFIG_H
+# Build libpopt on target
+include $(CLEAR_VARS)
 
+LOCAL_SRC_FILES:= $(common_src)
+LOCAL_CFLAGS += -DHAVE_CONFIG_H
+LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libpopt
 
 include $(BUILD_STATIC_LIBRARY)
+
+# Build libpopt on host
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(common_src)
+LOCAL_CFLAGS += -DHAVE_CONFIG_H
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libpopt
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
diff --git a/libpopt/config.h b/libpopt/config.h
index 73a0817..bb10b9c 100644
--- a/libpopt/config.h
+++ b/libpopt/config.h
@@ -122,6 +122,7 @@
 #define HAVE_LONG_LONG 1
 
 /* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H /* already defined in system/core/include/arch/linux-arm/AndroidConfig.h */
 #define HAVE_MALLOC_H 1
 
 /* Define to 1 if you have the <mcheck.h> header file. */
@@ -213,7 +214,7 @@
 #undef HAVE_UINTMAX_T
 
 /* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
+#define HAVE_UNISTD_H 1
 
 /* Define if you have the 'unsigned long long' type. */
 #undef HAVE_UNSIGNED_LONG_LONG
diff --git a/libpp/Android.mk b/libpp/Android.mk
new file mode 100644
index 0000000..77d00ee
--- /dev/null
+++ b/libpp/Android.mk
@@ -0,0 +1,45 @@
+LOCAL_PATH:= $(call my-dir)
+
+# Build libpp on host
+ifeq ($(HAVE_LIBBFD),true)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	arrange_profiles.cpp \
+	callgraph_container.cpp \
+	diff_container.cpp \
+	filename_spec.cpp \
+	format_output.cpp \
+	image_errors.cpp \
+	locate_images.cpp \
+	name_storage.cpp \
+	op_header.cpp \
+	symbol.cpp \
+	parse_filename.cpp \
+	populate.cpp \
+	profile.cpp \
+	profile_container.cpp \
+	profile_spec.cpp \
+	sample_container.cpp \
+	symbol_container.cpp \
+	symbol_functors.cpp \
+	symbol_sort.cpp \
+	xml_utils.cpp \
+	populate_for_spu.cpp
+
+LOCAL_C_INCLUDES := \
+	external/oprofile \
+	external/oprofile/libop \
+	external/oprofile/libutil \
+	external/oprofile/libdb \
+	external/oprofile/libopt++ \
+	external/oprofile/libutil++ \
+	external/oprofile/libop++ \
+	external/oprofile/libregex
+
+LOCAL_CFLAGS := -fexceptions -DANDROID_HOST
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libpp
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+endif
diff --git a/libregex/Android.mk b/libregex/Android.mk
new file mode 100644
index 0000000..3303869
--- /dev/null
+++ b/libregex/Android.mk
@@ -0,0 +1,20 @@
+LOCAL_PATH:= $(call my-dir)
+
+# Build libregex on host
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	op_regex.cpp \
+	demangle_symbol.cpp \
+	demangle_java_symbol.cpp
+
+LOCAL_C_INCLUDES := \
+	external/oprofile \
+	external/oprofile/libutil++
+
+LOCAL_CFLAGS := -fexceptions -DANDROID_HOST
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libop_regex
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
diff --git a/libutil++/Android.mk b/libutil++/Android.mk
new file mode 100644
index 0000000..138ff7f
--- /dev/null
+++ b/libutil++/Android.mk
@@ -0,0 +1,34 @@
+LOCAL_PATH:= $(call my-dir)
+
+# Build libutil++ on host
+ifeq ($(HAVE_LIBBFD),true)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	bfd_support.cpp \
+	bfd_spu_support.cpp \
+	child_reader.cpp \
+	cverb.cpp \
+	file_manip.cpp \
+	glob_filter.cpp \
+	op_bfd.cpp \
+	op_exception.cpp \
+	op_spu_bfd.cpp \
+	path_filter.cpp \
+	stream_util.cpp \
+	string_filter.cpp \
+	string_manip.cpp \
+	xml_output.cpp
+
+LOCAL_C_INCLUDES := \
+	external/oprofile \
+	external/oprofile/libutil \
+	external/oprofile/libop \
+	external/oprofile/libpp
+
+LOCAL_CFLAGS := -fexceptions -DANDROID_HOST
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libutil++
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+endif
diff --git a/libutil/Android.mk b/libutil/Android.mk
index 6a7cf5d..2fdf04b 100644
--- a/libutil/Android.mk
+++ b/libutil/Android.mk
@@ -1,7 +1,6 @@
 LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
+common_src := \
 	op_cpufreq.c \
 	op_deviceio.c \
 	op_file.c \
@@ -14,9 +13,27 @@
 	op_string.c \
 	op_version.c
 
-LOCAL_C_INCLUDES := \
-	$(LOCAL_PATH)/..
+common_includes := \
+	external/oprofile
 
+# Build libutil on target
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(common_src)
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libutil
 
 include $(BUILD_STATIC_LIBRARY)
+
+# Build libutil on host
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(common_src)
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_CFLAGS := -fexceptions -DANDROID_HOST -DHAVE_XCALLOC
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libutil
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
diff --git a/opimport_pull b/opimport_pull
index ed820f0..b3a257c 100755
--- a/opimport_pull
+++ b/opimport_pull
@@ -10,28 +10,28 @@
     print "    -r : reuse the directory if it already exists"
     print "    dir: directory on the host to store profile results"
 
-if (len(sys.argv) > 5):
+if (len(sys.argv) <= 1 or len(sys.argv) > 5):
     PrintUsage()
     sys.exit(1)
 
-# identify 32-bit vs 64-bit platform
-stream = os.popen("uname -m")
-arch_name = stream.readline().rstrip("\n");
-stream.close()
-
-# default path is prebuilt/linux-x86/oprofile
-# for 64-bit OS, use prebuilt/linux-x86_64/oprofile instead
-if arch_name == "x86_64":
-    arch_path = "/../../linux-x86_64/oprofile"
-else:
-    arch_path = ""
-
+# find prebuilt event data
 try:
     oprofile_event_dir = os.environ['OPROFILE_EVENTS_DIR']
 except:
+    # TODO: We can remove this in the future since we pull the abi data
+    # off the device so we don't need it to be in the prebuilts directory.
     print "OPROFILE_EVENTS_DIR not set. Run \". envsetup.sh\" first"
     sys.exit(1)
 
+# find binaries
+try:
+    oprofile_bin_dir = os.environ['OPROFILE_BIN_DIR']
+except:
+    # TODO: This assumes that the bin dir is prebuilt.
+    # When the host libbfd dependency is resolved and we can compile oprofile
+    # on the host, we should use those binaries instead.
+    oprofile_bin_dir = oprofile_event_dir + '/bin'
+
 argv_next = 1
 if sys.argv[1] == "-s":
   if len(sys.argv) < 4:
@@ -69,6 +69,13 @@
     print "adb%s pull failure, exiting" % device
     sys.exit(1)
 
+# get the ABI information off the phone
+result = os.system("adb%s pull /data/oprofile/abi %s/abi "
+                   "> /dev/null 2>&1" % (device, output_dir))
+if result != 0:
+    print "adb%s pull failure, exiting" % device
+    sys.exit(1)
+
 # enter the destination directory
 os.chdir(output_dir)
 
@@ -112,12 +119,11 @@
     if not os.path.exists(dir):
         os.makedirs(dir)
 
-    cmd = oprofile_event_dir + arch_path + "/bin/opimport -a " + \
-          oprofile_event_dir + \
-          "/abi/arm_abi -o samples" + middle_part + "/" + file_name + " " + line
+    cmd = oprofile_bin_dir + "/opimport -a abi " \
+          + " -o samples" + middle_part + "/" + file_name + " " + line
     os.system(cmd)
 
 stream.close()
 
 # short summary of profiling results
-os.system(oprofile_event_dir + arch_path + "/bin/opreport --session-dir=.")
+os.system(oprofile_bin_dir + "/opreport --session-dir=.")
diff --git a/pp/Android.mk b/pp/Android.mk
new file mode 100644
index 0000000..869a1f5
--- /dev/null
+++ b/pp/Android.mk
@@ -0,0 +1,99 @@
+LOCAL_PATH:= $(call my-dir)
+
+common_src := common_option.cpp
+
+common_includes := \
+	external/oprofile \
+	external/oprofile/libutil \
+	external/oprofile/libop \
+	external/oprofile/libdb \
+	external/oprofile/libopt++ \
+	external/oprofile/libutil++ \
+	external/oprofile/libregex \
+	external/oprofile/libpp
+
+common_libs := \
+	libpp \
+	libop \
+	libutil \
+	libdb \
+	libop_regex \
+	libopt++ \
+	libutil++ \
+	libpopt \
+	libz
+
+common_cflags := -fexceptions -DANDROID_HOST
+common_ldlibs := -lbfd -liberty -lintl -liconv
+
+ifeq ($(HAVE_LIBBFD),true)
+
+# Build opreport
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	$(common_src) \
+	opreport.cpp \
+	opreport_options.cpp
+
+LOCAL_STATIC_LIBRARIES := $(common_libs)
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_LDLIBS := $(common_ldlibs)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE:= opreport
+
+include $(BUILD_HOST_EXECUTABLE)
+
+# Build opannotate
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	$(common_src) \
+	opannotate.cpp \
+	opannotate_options.cpp
+
+LOCAL_STATIC_LIBRARIES := $(common_libs)
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_LDLIBS := $(common_ldlibs)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE:= opannotate
+
+include $(BUILD_HOST_EXECUTABLE)
+
+# Build opgprof
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	$(common_src) \
+	opgprof.cpp \
+	opgprof_options.cpp
+
+LOCAL_STATIC_LIBRARIES := $(common_libs)
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_LDLIBS := $(common_ldlibs)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE:= opgprof
+
+include $(BUILD_HOST_EXECUTABLE)
+
+# Build oparchive
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	$(common_src) \
+	oparchive.cpp \
+	oparchive_options.cpp
+
+LOCAL_STATIC_LIBRARIES := $(common_libs)
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_LDLIBS := $(common_ldlibs)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE:= oparchive
+
+include $(BUILD_HOST_EXECUTABLE)
+
+endif