[PATCH 1/3][build] Update build rule for executable with PRIVATE_ALL_WHOLE_STATIC_LIBRARIES

66 views
Skip to first unread message

Kito Cheng

unread,
Dec 1, 2011, 4:01:17 PM12/1/11
to 0xlab...@googlegroups.com
Change-Id: I82f3e92de547630613a8573faadccc2e36803604
---
core/combo/TARGET_linux-arm.mk | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index 5303238..ed4bf58 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -257,6 +257,9 @@ $(TARGET_CXX) -nostdlib -Bdynamic -Wl,-T,$(BUILD_SYSTEM)/armelf.x \
-o $@ \
$(TARGET_GLOBAL_LD_DIRS) \
-Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
+ -Wl,--whole-archive \
+ $(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ -Wl,--no-whole-archive \
$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
$(TARGET_CRTBEGIN_DYNAMIC_O) \
$(PRIVATE_ALL_OBJECTS) \
@@ -277,6 +280,9 @@ $(TARGET_CXX) -nostdlib -Bstatic -Wl,-T,$(BUILD_SYSTEM)/armelf.x \
$(TARGET_GLOBAL_LDFLAGS) \
$(PRIVATE_LDFLAGS) \
$(PRIVATE_ALL_OBJECTS) \
+ -Wl,--whole-archive \
+ $(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ -Wl,--no-whole-archive \
$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
$(TARGET_FDO_LIB) \
$(TARGET_LIBGCC) \
--
1.7.7.3

Kito Cheng

unread,
Dec 1, 2011, 4:01:18 PM12/1/11
to 0xlab...@googlegroups.com
Change-Id: I8cd9b64bd523a23f28bf901ddc0be7f01eadeaf1
---
tools/aprof/Android.mk | 40 ++++++++++
tools/aprof/Aprof.cpp | 113 +++++++++++++++++++++++++++
tools/aprof/Aprof.h | 34 ++++++++
tools/aprof/Edge.cpp | 10 +++
tools/aprof/Edge.h | 22 +++++
tools/aprof/Image.cpp | 162 +++++++++++++++++++++++++++++++++++++++
tools/aprof/Image.h | 42 ++++++++++
tools/aprof/ImageCollection.cpp | 70 +++++++++++++++++
tools/aprof/ImageCollection.h | 31 ++++++++
tools/aprof/Options.cpp | 148 +++++++++++++++++++++++++++++++++++
tools/aprof/Options.h | 28 +++++++
tools/aprof/Symbol.cpp | 140 +++++++++++++++++++++++++++++++++
tools/aprof/Symbol.h | 59 ++++++++++++++
tools/aprof/SymbolTable.cpp | 144 ++++++++++++++++++++++++++++++++++
tools/aprof/SymbolTable.h | 33 ++++++++
tools/aprof/common.h | 28 +++++++
tools/aprof/debug.h | 88 +++++++++++++++++++++
tools/aprof/main.cpp | 8 ++
18 files changed, 1200 insertions(+), 0 deletions(-)
create mode 100644 tools/aprof/Android.mk
create mode 100644 tools/aprof/Aprof.cpp
create mode 100644 tools/aprof/Aprof.h
create mode 100644 tools/aprof/Edge.cpp
create mode 100644 tools/aprof/Edge.h
create mode 100644 tools/aprof/Image.cpp
create mode 100644 tools/aprof/Image.h
create mode 100644 tools/aprof/ImageCollection.cpp
create mode 100644 tools/aprof/ImageCollection.h
create mode 100644 tools/aprof/Options.cpp
create mode 100644 tools/aprof/Options.h
create mode 100644 tools/aprof/Symbol.cpp
create mode 100644 tools/aprof/Symbol.h
create mode 100644 tools/aprof/SymbolTable.cpp
create mode 100644 tools/aprof/SymbolTable.h
create mode 100644 tools/aprof/common.h
create mode 100644 tools/aprof/debug.h
create mode 100644 tools/aprof/main.cpp

diff --git a/tools/aprof/Android.mk b/tools/aprof/Android.mk
new file mode 100644
index 0000000..51c960c
--- /dev/null
+++ b/tools/aprof/Android.mk
@@ -0,0 +1,40 @@
+#
+# Android.mk for aprof
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_FORCE_STATIC_EXECUTABLE := true
+
+ifeq ($(TARGET_ARCH),arm)
+LOCAL_CFLAGS += -DARM_SPECIFIC_HACKS
+endif
+
+LOCAL_MODULE_TAGS := eng
+LOCAL_CFLAGS += -O0 -g3 -Wall
+LOCAL_CFLAGS += -Wall
+LOCAL_CFLAGS += -DDEBUG
+
+LOCAL_SRC_FILES := \
+ main.cpp \
+ Aprof.cpp \
+ Symbol.cpp \
+ SymbolTable.cpp \
+ Image.cpp \
+ ImageCollection.cpp \
+ Options.cpp
+# Edge.cpp \
+# Profiles.cpp \
+
+LOCAL_C_INCLUDES:= \
+ $(LOCAL_PATH)/ \
+ external/elfutils/libelf/ \
+ bionic/libaprof
+
+LOCAL_STATIC_LIBRARIES := libelf
+
+LOCAL_MODULE := aprof
+
+include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/aprof/Aprof.cpp b/tools/aprof/Aprof.cpp
new file mode 100644
index 0000000..de3e864
--- /dev/null
+++ b/tools/aprof/Aprof.cpp
@@ -0,0 +1,113 @@
+#include <stdint.h>
+#include <Aprof.h>
+#include <Options.h>
+#include <libaprof.h>
+
+#include <string.h>
+#include <assert.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <debug.h>
+
+Aprof::Aprof(const Options &options) :
+ mOptions(options),
+ mImages(options) {
+ /*
+ * Read the profiling file, and read symbols.
+ */
+ readProfileFile();
+ mImages.dumpHistogram();
+ PRINT("\nCall graph (explanation follows)\n\n");
+ mImages.dumpCallEdge();
+}
+
+Aprof::~Aprof() {
+}
+
+bool Aprof::readBins(FILE *fp, bool isExe) {
+ uint32_t base=0;
+ uint32_t size=0;
+ uint32_t binSize=0;
+ size_t binLen;
+ uint16_t *bins;
+ uint32_t name_len = 0;
+ char filename[PATH_MAX];
+ fread(&name_len, sizeof(uint32_t), 1, fp);
+ fread(filename, name_len, 1, fp);
+ filename[name_len] = '\0';
+ fread(&base, sizeof(uint32_t), 1, fp);
+ fread(&size, sizeof(uint32_t), 1, fp);
+ fread(&binSize, sizeof(uint32_t), 1, fp);
+ INFO("%s : base %x -> %x, bin size : %d\n",
+ filename, base, base+size, binSize);
+ binLen = binSize/sizeof(uint16_t);
+ bins = new uint16_t[binLen];
+ fread(bins, 1, binSize, fp);
+ Image *img = mImages.addImage(filename, base,
+ size, Bins(bins, bins+binLen),
+ isExe);
+ img->readSymbol();
+ delete []bins;
+ return true;
+}
+
+bool Aprof::readTos(FILE *fp) {
+ uint32_t edges, i;
+ uint32_t callerPC;
+ uint32_t calleePC;
+ uint32_t count;
+ fread(&edges, sizeof(uint32_t), 1, fp);
+ for (i=0;i<edges;i++) {
+ fread(&callerPC, sizeof(uint32_t), 1, fp);
+ fread(&calleePC, sizeof(uint32_t), 1, fp);
+ fread(&count, sizeof(uint32_t), 1, fp);
+ mImages.addEdge(callerPC, calleePC, count);
+ }
+ return true;
+}
+
+bool Aprof::readHeader(FILE *fp) {
+ const char aprof_tag[] = APROF_TAG;
+ char tag[APROF_TAG_LENGTH];
+ uint32_t version;
+ uint32_t sample_rate;
+ uint32_t pointer_size;
+
+ fread(&tag, APROF_TAG_LENGTH, 1, fp);
+ if (memcmp(tag, aprof_tag, APROF_TAG_LENGTH)) {
+ return false;
+ }
+
+ fread(&version, sizeof(uint32_t), 1, fp);
+ fread(&sample_rate, sizeof(uint32_t), 1, fp);
+ fread(&pointer_size, sizeof(uint32_t), 1, fp);
+
+ FAILIF(pointer_size != 4, "Dont's support pointer size other than 4 now.");
+ return true;
+}
+
+bool Aprof::readProfileFile() {
+ FILE *fp = fopen(mOptions.profFile.c_str(), "r");
+ if (fp == NULL) return -1;
+ FAILIF(!readHeader(fp), "%s : bad aprof profiling file\n",
+ mOptions.profFile.c_str());
+ uint32_t header_type;
+ while ( fread(&header_type, sizeof(uint32_t), 1, fp) ) {
+ switch (header_type) {
+ case APROF_EXECUTABLE_HISTOGRAM_HEADER:
+ readBins(fp, true);
+ break;
+ case APROF_HISTOGRAM_HEADER:
+ readBins(fp, false);
+ break;
+ case APROF_CALL_GRAPH_HEADER:
+ readTos(fp);
+ break;
+ default:
+ FAILIF(1, "unknown type\n");
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/tools/aprof/Aprof.h b/tools/aprof/Aprof.h
new file mode 100644
index 0000000..a7ffa70
--- /dev/null
+++ b/tools/aprof/Aprof.h
@@ -0,0 +1,34 @@
+#ifndef _PROFILES_H
+#define _PROFILES_H
+
+#include <stdint.h>
+#include <string>
+#include <stdio.h>
+#include <elf.h>
+#include <list>
+#include <vector>
+#include <map>
+#include <Options.h>
+#include <SymbolTable.h>
+#include <ImageCollection.h>
+
+class Options;
+
+class Aprof {
+public:
+ Aprof(const Options &options);
+ ~Aprof();
+
+private:
+ Options mOptions;
+ ImageCollection mImages;
+
+ bool readHeader(FILE *fp);
+ bool readProfileFile();
+ bool readBins(FILE *fp, bool isExe);
+ bool readTos(FILE *fp);
+ bool readSymbols();
+ void updateHistogram();
+};
+
+#endif /* _PROFILES_H */
diff --git a/tools/aprof/Edge.cpp b/tools/aprof/Edge.cpp
new file mode 100644
index 0000000..bf0d492
--- /dev/null
+++ b/tools/aprof/Edge.cpp
@@ -0,0 +1,10 @@
+#include <Edge.h>
+#include <stddef.h>
+
+Edge::Edge(uint32_t from, uint32_t dest, uint32_t count):
+ from(from),
+ fromSym(NULL),
+ dest(dest),
+ destSym(NULL),
+ count(count) {
+}
diff --git a/tools/aprof/Edge.h b/tools/aprof/Edge.h
new file mode 100644
index 0000000..2229e48
--- /dev/null
+++ b/tools/aprof/Edge.h
@@ -0,0 +1,22 @@
+#ifndef _EDGE_H
+#define _EDGE_H
+
+#include <list>
+#include <stdint.h>
+
+class Image;
+class Symbol;
+
+class Edge {
+public:
+ Edge(uint32_t from, uint32_t dest, uint32_t count);
+ uint32_t from;
+ Symbol *fromSym;
+ uint32_t dest;
+ Symbol *destSym;
+ uint32_t count;
+};
+
+typedef std::list<Edge*> EdgeCollection;
+
+#endif /* _EDGE_H */
diff --git a/tools/aprof/Image.cpp b/tools/aprof/Image.cpp
new file mode 100644
index 0000000..b1f5317
--- /dev/null
+++ b/tools/aprof/Image.cpp
@@ -0,0 +1,162 @@
+#include <Image.h>
+#include <Options.h>
+#include <gelf.h>
+#include <debug.h>
+
+#include <string.h>
+#include <stdint.h>
+#include <assert.h>
+#include <limits.h>
+#include <fcntl.h>
+
+Image::Image(const std::string &imageName, uint32_t base,
+ uint32_t size, const Bins &bins,
+ const Options &options, bool isExe) :
+ mOptions(options),
+ mImageName(imageName),
+ mBase(base),
+ mSize(size),
+ mBins(bins),
+ mSymbolTable(this,
+ std::string("<")+imageName+std::string(">"),
+ base),
+ mUpdateHistogramFlag(false),
+ mIsExecutable(isExe) {
+}
+
+Image::~Image() {
+}
+
+bool Image::addrInImage(uint32_t addr) {
+ return (addr >= mBase &&
+ addr < (mBase+mSize));
+}
+
+Symbol *Image::querySymbol(uint32_t addr) {
+ return mSymbolTable.find(addr);
+}
+
+void Image::dumpHistogram(uintmax_t totalTime) {
+ updateHistogram();
+ mSymbolTable.dumpHistogram(totalTime, mOptions);
+}
+
+void Image::updateHistogram() {
+ if (mUpdateHistogramFlag) return;
+ mUpdateHistogramFlag = true;
+ size_t i, binLen = mBins.size();
+ for (i=0;i<binLen;++i) {
+ if (mBins[i] == 0) continue;
+ uint32_t addr = (i * 2 * 2) + mBase;
+ Symbol *symbol = mSymbolTable.find(addr);
+ INFO("Symbol %s(%x) : %d ms\n",
+ symbol->getName().c_str(),
+ addr, mBins[i] *(1000/100));
+ symbol->setSelfTime(symbol->getSelfTime() + mBins[i]);
+ }
+
+ mSymbolTable.updateCumulativeTime();
+}
+
+int findFile(const std::string &filename,
+ const Options &options) {
+ const LibPaths &libPaths = options.libPaths;
+ int fd;
+ if (filename == basename(options.imgFile.c_str()) ) {
+ fd = open(options.imgFile.c_str(), O_RDONLY);
+ if (fd > 0) return fd;
+ }
+
+ fd = open(filename.c_str(), O_RDONLY);
+ if (fd > 0) return fd;
+ for (LibPaths::const_iterator itr = libPaths.begin();
+ itr != libPaths.end();
+ ++itr) {
+ std::string path = *itr;
+ path += "/";
+ path += filename;
+ fd = open(path.c_str(), O_RDONLY);
+ if (fd >0) return fd;
+ }
+ INFO("Can't found %s\n", filename.c_str());
+ return -1;
+}
+
+bool Image::readSymbol() {
+ int fd = findFile(mImageName, mOptions);
+ mUpdateHistogramFlag = false;
+
+ if (fd < 0) return false;
+ FAILIF (elf_version(EV_CURRENT) == EV_NONE, "libelf is out of date!\n");
+ Elf *elf = elf_begin(fd, ELF_C_READ, NULL);
+ if (elf_kind(elf) != ELF_K_ELF) {
+ return false;
+ }
+
+ Elf_Scn *scn = NULL;
+ GElf_Shdr shdr;
+ GElf_Ehdr ehdr;
+ size_t shstrndx;
+ FAILIF_LIBELF(elf_getshstrndx(elf, &shstrndx) < 0,
+ elf_getshstrndx);
+ FAILIF_LIBELF(0 == gelf_getehdr(elf, &ehdr), gelf_getehdr);
+
+ while ((scn = elf_nextscn (elf, scn)) != NULL) {
+ FAILIF_LIBELF(NULL == gelf_getshdr(scn, &shdr), gelf_getshdr);
+ const char *section_name = elf_strptr(elf, shstrndx, shdr.sh_name);
+ if (strcmp(section_name, ".plt") == 0) {
+ /* Insert <image_name>@plt symbol to symbol table */
+ mSymbolTable.insertPltSymbol(shdr.sh_addr+mBase,
+ shdr.sh_size);
+ }
+ if (SHT_SYMTAB == shdr.sh_type) {
+ Elf_Data *symdata;
+ size_t elsize;
+ symdata = elf_getdata (scn, NULL); /* get the symbol data */
+ FAILIF_LIBELF(NULL == symdata, elf_getdata);
+
+ size_t shnum;
+ FAILIF_LIBELF(elf_getshnum (elf, &shnum) < 0, elf_getshnum);
+ elsize = gelf_fsize(elf, ELF_T_SYM, 1, ehdr.e_version);
+
+ size_t index;
+ for (index = 0; index < symdata->d_size / elsize; index++) {
+ const char *symName;
+ GElf_Sym sym_mem;
+ GElf_Sym *sym;
+ /* Get the symbol. */
+ sym = gelf_getsymshndx (symdata, NULL,
+ index, &sym_mem, NULL);
+ FAILIF_LIBELF(sym == NULL, gelf_getsymshndx);
+ /* We only care about function here. */
+ if (ELF32_ST_TYPE(sym->st_info) != STT_FUNC) {
+ continue;
+ }
+ /* Insert to symbol talbe if not undefine symbol */
+ if (sym->st_shndx != SHN_UNDEF &&
+ sym->st_shndx < shnum) {
+ symName = elf_strptr(elf, shdr.sh_link, sym->st_name);
+ Symbol *symbol = mSymbolTable.insert(symName,
+ sym->st_value+mBase,
+ sym->st_size);
+ INFO("Symbol %s, address : %x size : %x\n", symName,
+ symbol->getAddr(),
+ symbol->getSize());
+ }
+ }
+ }
+
+ }
+ elf_end(elf);
+ close(fd);
+
+ return true;
+}
+
+const std::string &Image::getName() const{
+ return mImageName;
+}
+
+void Image::dumpCallEdge() {
+ mSymbolTable.dumpCallEdge(mOptions);
+}
diff --git a/tools/aprof/Image.h b/tools/aprof/Image.h
new file mode 100644
index 0000000..20cac76
--- /dev/null
+++ b/tools/aprof/Image.h
@@ -0,0 +1,42 @@
+#ifndef _IMAGE_H
+#define _IMAGE_H
+
+#include <Options.h>
+#include <SymbolTable.h>
+
+#include <map>
+#include <string>
+#include <vector>
+#include <stdint.h>
+
+typedef std::map<Symbol*, uint32_t> Histogram;
+typedef std::vector<uint16_t> Bins;
+
+class Image {
+public:
+
+ Image(const std::string &imageName, uint32_t base,
+ uint32_t size, const Bins &bins,
+ const Options &options, bool isExe);
+ ~Image();
+
+ const std::string &getName() const;
+ bool readSymbol();
+ void updateHistogram();
+ bool addrInImage(uint32_t addr);
+ Symbol *querySymbol(uint32_t addr);
+ void dumpCallEdge();
+ void dumpHistogram(uintmax_t totalTime);
+
+private:
+ const Options &mOptions;
+ std::string mImageName;
+ uint32_t mBase;
+ uint32_t mSize;
+ Bins mBins;
+ SymbolTable mSymbolTable;
+ bool mUpdateHistogramFlag;
+ bool mIsExecutable;
+};
+
+#endif /* _IMAGE_H */
diff --git a/tools/aprof/ImageCollection.cpp b/tools/aprof/ImageCollection.cpp
new file mode 100644
index 0000000..21ed4c4
--- /dev/null
+++ b/tools/aprof/ImageCollection.cpp
@@ -0,0 +1,70 @@
+#include <ImageCollection.h>
+
+ImageCollection::ImageCollection(const Options &options) :
+ mImages(),
+ mOptions(options),
+ mTotalTime(0) {
+}
+
+Image *ImageCollection::addImage(const std::string &imageName,
+ uint32_t base,
+ uint32_t size,
+ const Bins &bins,
+ bool isExe) {
+ Image *img = new Image(imageName, base, size, bins, mOptions, isExe);
+ mImages.push_back(img);
+ for (Bins::const_iterator itr = bins.begin();
+ itr != bins.end();
+ ++itr) {
+ mTotalTime += *itr;
+ }
+ return img;
+}
+
+void ImageCollection::dumpHistogram() {
+ PRINT(" %% cumulative self ");
+ PRINT(" self total\n");
+ PRINT(" time seconds seconds");
+ PRINT(" calls ms/call ms/call name\n");
+ for (_ImageCollection::iterator itr = mImages.begin();
+ itr != mImages.end();
+ ++itr) {
+ (*itr)->updateHistogram();
+ }
+ for (_ImageCollection::iterator itr = mImages.begin();
+ itr != mImages.end();
+ ++itr) {
+ (*itr)->dumpHistogram(mTotalTime);
+ }
+}
+
+Image *ImageCollection::findImage(uint32_t addr) {
+ for (_ImageCollection::iterator itr = mImages.begin();
+ itr != mImages.end();
+ ++itr) {
+ if ((*itr)->addrInImage(addr)) {
+ return *itr;
+ }
+ }
+ return NULL;
+}
+
+void ImageCollection::dumpCallEdge() {
+ for (_ImageCollection::iterator itr = mImages.begin();
+ itr != mImages.end();
+ ++itr) {
+ Image *img = *itr;
+ img->dumpCallEdge();
+ }
+}
+
+void ImageCollection::addEdge(uint32_t callerPC,
+ uint32_t calleePC,
+ uint32_t count) {
+ Image *callerImg = findImage(callerPC);
+ Symbol *caller = callerImg->querySymbol(callerPC);
+ Image *calleeImg = findImage(calleePC);
+ Symbol *callee = calleeImg->querySymbol(calleePC);
+ caller->addCalledSymbol(callee, count);
+ callee->addCallBySymbol(caller, count);
+}
diff --git a/tools/aprof/ImageCollection.h b/tools/aprof/ImageCollection.h
new file mode 100644
index 0000000..4064de9
--- /dev/null
+++ b/tools/aprof/ImageCollection.h
@@ -0,0 +1,31 @@
+#ifndef _IMAGE_COLLECTION_H
+#define _IMAGE_COLLECTION_H
+
+#include <Image.h>
+#include <Edge.h>
+#include <Options.h>
+#include <debug.h>
+
+#include <list>
+#include <stdint.h>
+
+class ImageCollection {
+public:
+ ImageCollection(const Options &options);
+ void insert(Image *img);
+ Image *addImage(const std::string &imageName, uint32_t base,
+ uint32_t size, const Bins &bins, bool isExe);
+ void updateHistogram();
+ Image *findImage(uint32_t addr);
+ void addEdge(uint32_t callerPC, uint32_t calleePC, uint32_t count);
+
+ void dumpCallEdge();
+ void dumpHistogram();
+private:
+ typedef std::list<Image*> _ImageCollection;
+ _ImageCollection mImages;
+ const Options &mOptions;
+ uintmax_t mTotalTime;
+};
+
+#endif /* _IMAGE_COLLECTION_H */
diff --git a/tools/aprof/Options.cpp b/tools/aprof/Options.cpp
new file mode 100644
index 0000000..186f922
--- /dev/null
+++ b/tools/aprof/Options.cpp
@@ -0,0 +1,148 @@
+#include <Options.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <debug.h>
+
+extern char *optarg;
+extern int optind, opterr, optopt;
+int quiet_flag;
+int verbose;
+
+static struct option long_options[] = {
+ {"quiet", no_argument, 0, 'Q'},
+ {"lookup", required_argument, 0, 'L'},
+ {"verbose", no_argument, 0, 'v'},
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0},
+};
+
+/* This array must parallel long_options[] */
+static const char *descriptions[] = {
+ "suppress informational and non-fatal error messages",
+ "provide a directory for library lookup",
+ "print verbose output",
+ "print help screen",
+};
+
+
+static void print_help(const char *name) {
+ fprintf(stdout,
+ "invokation:\n"
+ "\t%s executable_file -Ldir1 [-Ldir2 ...]\n"
+ "\t%s executable_file profiling_file -Ldir1 [-Ldir2 ...]\n"
+ "\t%s -h\n\n", name, name, name);
+ fprintf(stdout, "options:\n");
+ struct option *opt = long_options;
+ const char **desc = descriptions;
+ while (opt->name) {
+ fprintf(stdout, "\t-%c/--%s%s: %s\n",
+ opt->val,
+ opt->name,
+ (opt->has_arg ? " (argument)" : ""),
+ *desc);
+ opt++;
+ desc++;
+ }
+}
+
+void Options::parseCmdLine(int argc, char **argv) {
+ int c;
+
+ while (1) {
+ /* getopt_long stores the option index here. */
+ int option_index = 0;
+
+ c = getopt_long (argc, argv,
+ "QL:vh",
+ long_options,
+ &option_index);
+ /* Detect the end of the options. */
+ if (c == -1) break;
+
+ if (isgraph(c)) {
+ INFO ("option -%c with value `%s'\n", c, (optarg ?: "(null)"));
+ }
+
+#define SET_STRING_OPTION(name) do { \
+ ASSERT(optarg); \
+ (*name) = strdup(optarg); \
+} while(0)
+
+#define SET_REPEATED_STRING_OPTION(arr, num, size) do { \
+ if (*num == size) { \
+ size += 10; \
+ *arr = (char **)REALLOC(*arr, size * sizeof(char *)); \
+ } \
+ SET_STRING_OPTION(((*arr) + *num)); \
+ (*num)++; \
+} while(0)
+
+#define SET_INT_OPTION(val) do { \
+ ASSERT(optarg); \
+ if (strlen(optarg) >= 2 && optarg[0] == '0' && optarg[1] == 'x') { \
+ FAILIF(1 != sscanf(optarg+2, "%x", val), \
+ "Expecting a hexadecimal argument!\n"); \
+ } else { \
+ FAILIF(1 != sscanf(optarg, "%d", val), \
+ "Expecting a decimal argument!\n"); \
+ } \
+} while(0)
+
+ switch (c) {
+ case 0:
+ /* If this option set a flag, do nothing else now. */
+ if (long_options[option_index].flag != 0)
+ break;
+ INFO ("option %s", long_options[option_index].name);
+ if (optarg)
+ INFO (" with arg %s", optarg);
+ INFO ("\n");
+ break;
+ case 'L':
+ libPaths.push_back(optarg);
+ break;
+ case 'h': print_help(argv[0]); exit(1); break;
+ case 'v': verbose = 1; break;
+ case '?':
+ /* getopt_long already printed an error message. */
+ break;
+
+#undef SET_STRING_OPTION
+#undef SET_REPEATED_STRING_OPTION
+#undef SET_INT_OPTION
+
+ default:
+ FAILIF(1, "Unknown option");
+ }
+ }
+
+ switch (argc - optind) {
+ case 1:
+ imgFile = argv[optind];
+ profFile = "agmon.out";
+ break;
+ case 2:
+ imgFile = argv[optind];
+ profFile = argv[optind+1];
+ break;
+ default:
+ print_help(argv[0]); exit(1);
+ break;
+ }
+}
+
+Options::Options(int argc, char **argv) {
+ parseCmdLine(argc, argv);
+ INFO("Image file : %s\n", imgFile.c_str());
+ INFO("Profile file : %s\n", profFile.c_str());
+ for (std::vector<std::string>::iterator itr = libPaths.begin();
+ itr != libPaths.end();
+ ++itr) {
+ INFO("lib path : %s \n", itr->c_str());
+ }
+};
+
+static const uintmax_t one_second = 1000;
+uintmax_t Options::toMS(uintmax_t time) const {
+ return time * (one_second / sampleRate);
+};
diff --git a/tools/aprof/Options.h b/tools/aprof/Options.h
new file mode 100644
index 0000000..8bee430
--- /dev/null
+++ b/tools/aprof/Options.h
@@ -0,0 +1,28 @@
+#ifndef _OPTIONS_H
+#define _OPTIONS_H
+
+#include <string>
+#include <vector>
+#include <stdint.h>
+
+typedef std::vector<std::string> LibPaths;
+extern int verbose;
+
+class Options {
+public:
+ Options(int argc, char **argv);
+
+ std::string imgFile;
+ std::string profFile;
+ LibPaths libPaths;
+
+ uint32_t version;
+ uint32_t sampleRate;
+ uint32_t pointerSize;
+
+ uintmax_t toMS(uintmax_t time) const;
+private:
+ void parseCmdLine(int argc, char **argv);
+};
+
+#endif
diff --git a/tools/aprof/Symbol.cpp b/tools/aprof/Symbol.cpp
new file mode 100644
index 0000000..3d4a222
--- /dev/null
+++ b/tools/aprof/Symbol.cpp
@@ -0,0 +1,140 @@
+#include <Symbol.h>
+#include <Options.h>
+#include <stdio.h>
+#include <debug.h>
+
+Symbol::Symbol(Image *img, const std::string &name,
+ uint32_t addr, uint32_t size) :
+ mImg(img),
+ mName(name),
+#ifdef ARM_SPECIFIC_HACKS
+ /* If the symbol addresses a Thumb instruction,
+ the value of address with bit zero set;
+ so just discard it here.
+ */
+ mAddr(addr & (~(uint32_t)(1))),
+#else
+ mAddr(addr),
+#endif
+ mSize(size),
+ mCumulativeTime(0),
+ mSelfTime(0),
+ mCalled(),
+ mCallBy() {
+}
+
+const std::string &Symbol::getName() const{
+ return mName;
+}
+
+uint32_t Symbol::getAddr() const{
+ return mAddr;
+}
+
+uint32_t Symbol::getSize() const{
+ return mSize;
+}
+
+uintmax_t Symbol::getCumulativeTime() const{
+ return mCumulativeTime;
+}
+
+uintmax_t Symbol::getSelfTime() const{
+ return mSelfTime;
+}
+
+void Symbol::setCumulativeTime(uintmax_t time) {
+ mCumulativeTime = time;
+}
+
+void Symbol::setSelfTime(uintmax_t time) {
+ mSelfTime = time;
+}
+
+bool Symbol::inSameImage(const Symbol *sym) const {
+ return sym->mImg == this->mImg;
+}
+
+void Symbol::dumpHistogram(uintmax_t totalTime, const Options &options) {
+ if (mCumulativeTime != 0 ||
+ mSelfTime != 0 ||
+ !mCalled.empty()){
+ uintmax_t called = 0;
+ for (CallInfo::iterator itr = mCallBy.begin();
+ itr != mCallBy.end();
+ ++itr) {
+ called += itr->second;
+ }
+ double percent = mSelfTime/(double)totalTime*100.0;
+ uintmax_t selfTimePerCall = 0;
+ uintmax_t cumuTimePerCall = 0;
+ if (called) {
+ selfTimePerCall = mSelfTime/called;
+ cumuTimePerCall = mCumulativeTime/called;
+ }
+ PRINT("%6.2f %10jd %10jd ",
+ percent,
+ options.toMS(mCumulativeTime),
+ options.toMS(mSelfTime));
+ PRINT("%10jd %10jd %10jd %s\n",
+ called, selfTimePerCall,
+ cumuTimePerCall, getName().c_str());
+ }
+}
+
+void Symbol::updateCumulativeTime(uintmax_t cumulativeTime) {
+ INFO(" Update cumulative time for %s...\n", getName().c_str());
+ this->mCumulativeTime += cumulativeTime;
+ for (CallInfo::iterator itr = mCallBy.begin();
+ itr != mCallBy.end();
+ ++itr) {
+ Symbol *sym = itr->first;
+ if (sym->tag != tag) {
+ sym->tag = tag; /* make sure only traversal once */
+ sym->updateCumulativeTime(cumulativeTime);
+ }
+ }
+}
+
+void Symbol::updateCumulativeTime() {
+ tag = this;
+ if (mSelfTime == 0) return;
+ INFO("Update cumulative time from %s...\n", getName().c_str());
+ for (CallInfo::iterator itr = mCallBy.begin();
+ itr != mCallBy.end();
+ ++itr) {
+ Symbol *sym = itr->first;
+ if (sym->tag != tag) {
+ sym->tag = tag; /* make sure only traversal once */
+ sym->updateCumulativeTime(mSelfTime);
+ }
+ }
+}
+
+void Symbol::addCalledSymbol(Symbol *sym, unsigned count) {
+ mCalled[sym] += count;
+}
+
+void Symbol::addCallBySymbol(Symbol *sym, unsigned count) {
+ mCallBy[sym] += count;
+}
+
+void Symbol::dumpCallByInfo(const Options &options) const {
+ if (mCumulativeTime == 0 &&
+ mSelfTime == 0 &&
+ mCallBy.empty()) return;
+ PRINT(" %-18s %10jd %10jd\n", getName().c_str(),
+ getCumulativeTime(),
+ getSelfTime());
+ for (CallInfo::const_iterator itr = mCallBy.begin();
+ itr != mCallBy.end();
+ ++itr) {
+ const Symbol *sym = itr->first;
+ unsigned count = itr->second;
+ double timePercent = 100.0;
+ PRINT(" %2.2f", timePercent);
+ PRINT(" %10jd", options.toMS(sym->getCumulativeTime()));
+ PRINT(" %10jd", options.toMS(sym->getSelfTime()));
+ PRINT(" %10u %s\n", count, sym->getName().c_str());
+ }
+}
diff --git a/tools/aprof/Symbol.h b/tools/aprof/Symbol.h
new file mode 100644
index 0000000..a494225
--- /dev/null
+++ b/tools/aprof/Symbol.h
@@ -0,0 +1,59 @@
+#ifndef _SYMBOL_H
+#define _SYMBOL_H
+
+#include <vector>
+#include <map>
+#include <string>
+#include <stdint.h>
+
+class Image;
+class Symbol;
+class Options;
+
+typedef std::map<Symbol *, unsigned> CallInfo;
+
+class Symbol {
+public:
+ Symbol(Image *img, const std::string &name,
+ uint32_t addr, uint32_t size);
+
+ const std::string &getName() const;
+ uint32_t getAddr() const;
+ uint32_t getSize() const;
+
+ uintmax_t getCumulativeTime() const;
+ uintmax_t getSelfTime() const;
+
+ void setCumulativeTime(uintmax_t time);
+ void setSelfTime(uintmax_t time);
+
+ void dumpHistogram(uintmax_t totalTime, const Options &options);
+ void updateCumulativeTime();
+
+ bool inSameImage(const Symbol *sym) const;
+
+ void addCalledSymbol(Symbol *sym, unsigned count);
+ void addCallBySymbol(Symbol *sym, unsigned count);
+
+ void dumpCallByInfo(const Options &options) const;
+private:
+ void updateCumulativeTime(uintmax_t cumulativeTime);
+
+ Image *mImg;
+ std::string mName;
+ uint32_t mAddr;
+ uint32_t mSize;
+
+ uintmax_t mCumulativeTime;
+ uintmax_t mSelfTime;
+
+ CallInfo mCalled;
+ CallInfo mCallBy;
+
+ /*
+ * Use for update cumulative time
+ */
+ Symbol *tag;
+};
+
+#endif
diff --git a/tools/aprof/SymbolTable.cpp b/tools/aprof/SymbolTable.cpp
new file mode 100644
index 0000000..1adb8e7
--- /dev/null
+++ b/tools/aprof/SymbolTable.cpp
@@ -0,0 +1,144 @@
+#include <SymbolTable.h>
+#include <Image.h>
+
+#include <debug.h>
+
+#include <algorithm>
+
+SymbolTable::SymbolTable(Image *img, const std::string &defaultSymbol,
+ uint32_t base) :
+ mImg(img),
+ mSortedFlag(false),
+ mCumulativeTimeUpdatedFlag(false),
+ mSymbols(),
+ mDefaultSymbol(new Symbol(img, defaultSymbol, base, 0)),
+ mPltSymbol(NULL) {
+}
+
+Symbol *SymbolTable::insert(const std::string &name,
+ uint32_t addr,
+ uint32_t size) {
+ mSortedFlag = false;
+ mCumulativeTimeUpdatedFlag = false;
+ Symbol *sym = new Symbol(mImg, name, addr, size);
+ mSymbols.push_back(sym);
+ return sym;
+}
+
+Symbol *SymbolTable::insertPltSymbol(uint32_t addr, uint32_t size) {
+ FAILIF(mPltSymbol != NULL, "PLT Symbol already set in %s!", mImg->getName().c_str());
+ std::string pltSymbolName = mImg->getName() + "@plt";
+ mPltSymbol = new Symbol(mImg, pltSymbolName, addr, size);
+ return mPltSymbol;
+}
+
+static bool symbolCmp(const Symbol *lhs, const Symbol *rhs) {
+ return lhs->getAddr() < rhs->getAddr();
+}
+
+void SymbolTable::sortSymbol() {
+ if (!mSortedFlag) {
+ std::sort(mSymbols.begin(), mSymbols.end(), symbolCmp);
+ mSortedFlag = true;
+ }
+}
+
+void SymbolTable::dumpCallEdge(const Options &options) {
+ sortSymbol();
+ uintmax_t cumulativeTime = getCumulativeTime();
+ uintmax_t selfTime = getSelfTime();
+ if (cumulativeTime == 0 &&
+ selfTime == 0) {
+ return;
+ }
+ PRINT("-------------------------------------------------------------\n");
+ PRINT("Image : %s\n", mImg->getName().c_str());
+ PRINT("Cumulative time : %jd ms\n", options.toMS(cumulativeTime));
+ PRINT("Self time : %jd ms\n", options.toMS(selfTime));
+ PRINT(" Function %% time");
+ PRINT(" cumulative self");
+ PRINT(" Count Call by\n");
+ for (std::vector<Symbol*>::iterator itr = mSymbols.begin();
+ itr != mSymbols.end();
+ ++itr) {
+ Symbol *sym = *itr;
+ sym->dumpCallByInfo(options);
+ }
+}
+
+Symbol *SymbolTable::find(uint32_t addr) {
+ if (mSymbols.empty()) return mDefaultSymbol;
+ sortSymbol();
+ for (std::vector<Symbol*>::reverse_iterator itr = mSymbols.rbegin();
+ itr != mSymbols.rend();
+ ++itr) {
+ if (addr >= (*itr)->getAddr()) {
+ return (*itr);
+ }
+ }
+ if (mPltSymbol &&
+ addr >= mPltSymbol->getAddr() &&
+ addr < mPltSymbol->getAddr() + mPltSymbol->getSize() ) {
+ return mPltSymbol;
+ }
+ return mDefaultSymbol;
+}
+
+void SymbolTable::dump() {
+ sortSymbol();
+ for (std::vector<Symbol*>::iterator itr = mSymbols.begin();
+ itr != mSymbols.end();
+ ++itr) {
+ Symbol *sym = *itr;
+ PRINT("%16x %16x %s\n", sym->getAddr(),
+ sym->getSize(),
+ sym->getName().c_str());
+ }
+}
+
+void SymbolTable::dumpHistogram(uintmax_t totalTime, const Options &options) {
+ sortSymbol();
+ mDefaultSymbol->dumpHistogram(totalTime, options);
+ if (mPltSymbol) mPltSymbol->dumpHistogram(totalTime, options);
+ for (std::vector<Symbol*>::iterator itr = mSymbols.begin();
+ itr != mSymbols.end();
+ ++itr) {
+ (*itr)->dumpHistogram(totalTime, options);
+ }
+}
+
+uintmax_t SymbolTable::getCumulativeTime() {
+ uintmax_t cumulativeTime = mDefaultSymbol->getCumulativeTime();
+ for (std::vector<Symbol*>::iterator itr = mSymbols.begin();
+ itr != mSymbols.end();
+ ++itr) {
+ cumulativeTime += (*itr)->getCumulativeTime();
+ }
+ return cumulativeTime;
+}
+
+uintmax_t SymbolTable::getSelfTime() {
+ uintmax_t selfTime = mDefaultSymbol->getSelfTime();
+ for (std::vector<Symbol*>::iterator itr = mSymbols.begin();
+ itr != mSymbols.end();
+ ++itr) {
+ selfTime += (*itr)->getSelfTime();
+ }
+ return selfTime;
+}
+
+void SymbolTable::updateCumulativeTime(){
+ if (mCumulativeTimeUpdatedFlag) return;
+ mCumulativeTimeUpdatedFlag = true;
+
+ for (std::vector<Symbol*>::iterator itr = mSymbols.begin();
+ itr != mSymbols.end();
+ ++itr) {
+ (*itr)->setCumulativeTime(0);
+ }
+ for (std::vector<Symbol*>::iterator itr = mSymbols.begin();
+ itr != mSymbols.end();
+ ++itr) {
+ (*itr)->updateCumulativeTime();
+ }
+}
diff --git a/tools/aprof/SymbolTable.h b/tools/aprof/SymbolTable.h
new file mode 100644
index 0000000..87f18c1
--- /dev/null
+++ b/tools/aprof/SymbolTable.h
@@ -0,0 +1,33 @@
+#ifndef _SYMBOL_TABLE_H
+#define _SYMBOL_TABLE_H
+
+#include <Symbol.h>
+
+class SymbolTable {
+public:
+ SymbolTable(Image *img, const std::string &defaultSymbol, uint32_t base);
+ Symbol *insert(const std::string &name, uint32_t addr, uint32_t size);
+ Symbol *insertPltSymbol(uint32_t addr, uint32_t size);
+ Symbol *find(uint32_t addr);
+ void dump();
+ void dumpHistogram(uintmax_t totlaTime, const Options &options);
+ void dumpCallEdge(const Options &options);
+
+ uintmax_t getCumulativeTime();
+ uintmax_t getSelfTime();
+
+ void updateCumulativeTime();
+ Symbol *getDefaultSymbol();
+ Symbol *getPltSymbol();
+private:
+ Image *mImg;
+ void sortSymbol();
+ bool mSortedFlag;
+ bool mCumulativeTimeUpdatedFlag;
+ std::vector<Symbol*> mSymbols;
+ Symbol *mDefaultSymbol;
+ Symbol *mPltSymbol;
+};
+
+
+#endif /* _SYMBOL_TABLE_H */
diff --git a/tools/aprof/common.h b/tools/aprof/common.h
new file mode 100644
index 0000000..f5d9d2e
--- /dev/null
+++ b/tools/aprof/common.h
@@ -0,0 +1,28 @@
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <libelf.h>
+#include <elf.h>
+
+#define unlikely(expr) __builtin_expect (expr, 0)
+#define likely(expr) __builtin_expect (expr, 1)
+
+#define MIN(a,b) ((a)<(b)?(a):(b)) /* no side effects in arguments allowed! */
+
+static inline int is_host_little(void)
+{
+ short val = 0x10;
+ return ((char *)&val)[0] != 0;
+}
+
+static inline long switch_endianness(long val)
+{
+ long newval;
+ ((char *)&newval)[3] = ((char *)&val)[0];
+ ((char *)&newval)[2] = ((char *)&val)[1];
+ ((char *)&newval)[1] = ((char *)&val)[2];
+ ((char *)&newval)[0] = ((char *)&val)[3];
+ return newval;
+}
+
+#endif/*COMMON_H*/
diff --git a/tools/aprof/debug.h b/tools/aprof/debug.h
new file mode 100644
index 0000000..473f0d3
--- /dev/null
+++ b/tools/aprof/debug.h
@@ -0,0 +1,88 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <common.h>
+
+#ifdef DEBUG
+
+ #define FAILIF(cond, msg...) do { \
+ if (unlikely(cond)) { \
+ fprintf(stderr, "%s(%d): ", __FILE__, __LINE__); \
+ fprintf(stderr, ##msg); \
+ exit(1); \
+ } \
+} while(0)
+
+/* Debug enabled */
+ #define ASSERT(x) do { \
+ if (unlikely(!(x))) { \
+ fprintf(stderr, \
+ "ASSERTION FAILURE %s:%d: [%s]\n", \
+ __FILE__, __LINE__, #x); \
+ exit(1); \
+ } \
+} while(0)
+
+#else
+
+ #define FAILIF(cond, msg...) do { \
+ if (unlikely(cond)) { \
+ fprintf(stderr, ##msg); \
+ exit(1); \
+ } \
+} while(0)
+
+/* No debug */
+ #define ASSERT(x) do { } while(0)
+
+#endif/* DEBUG */
+
+#define FAILIF_LIBELF(cond, function) \
+ FAILIF(cond, "%s(): %s\n", #function, elf_errmsg(elf_errno()));
+
+static inline void *MALLOC(unsigned int size) {
+ void *m = malloc(size);
+ FAILIF(NULL == m, "malloc(%d) failed!\n", size);
+ return m;
+}
+
+static inline void *CALLOC(unsigned int num_entries, unsigned int entry_size) {
+ void *m = calloc(num_entries, entry_size);
+ FAILIF(NULL == m, "calloc(%d, %d) failed!\n", num_entries, entry_size);
+ return m;
+}
+
+static inline void *REALLOC(void *ptr, unsigned int size) {
+ void *m = realloc(ptr, size);
+ FAILIF(NULL == m, "realloc(%p, %d) failed!\n", ptr, size);
+ return m;
+}
+
+static inline void FREE(void *ptr) {
+ free(ptr);
+}
+
+static inline void FREEIF(void *ptr) {
+ if (ptr) FREE(ptr);
+}
+
+#define PRINT(x...) do { \
+ extern int quiet_flag; \
+ if(likely(!quiet_flag)) \
+ fprintf(stdout, ##x); \
+} while(0)
+
+#define ERROR PRINT
+
+#define INFO(x...) do { \
+ extern int verbose; \
+ if(unlikely(verbose)) \
+ fprintf(stdout, ##x); \
+} while(0)
+
+/* Prints a hex and ASCII dump of the selected buffer to the selected stream. */
+int dump_hex_buffer(FILE *s, void *b, size_t l, size_t elsize);
+
+#endif/*DEBUG_H*/
diff --git a/tools/aprof/main.cpp b/tools/aprof/main.cpp
new file mode 100644
index 0000000..dfa4956
--- /dev/null
+++ b/tools/aprof/main.cpp
@@ -0,0 +1,8 @@
+#include <Options.h>
+#include <Aprof.h>
+
+int main(int argc, char **argv) {
+ Options opts(argc, argv);
+ Aprof aprof(opts);
+ return 0;
+}
--
1.7.7.3

Kito Cheng

unread,
Dec 1, 2011, 4:01:19 PM12/1/11
to 0xlab...@googlegroups.com
Change-Id: I364ab13d322727420be05b00eedce2b18c8d7364
---
core/binary.mk | 10 ++++++++++
core/clear_vars.mk | 1 +
core/executable.mk | 13 +++++++++++++
core/shared_library.mk | 7 +++++++
core/static_library.mk | 7 +++++++
5 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/core/binary.mk b/core/binary.mk
index 8d41e94..4e299db 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -47,6 +47,16 @@ ifeq ($(strip $(LOCAL_NO_FDO_SUPPORT)),)
LOCAL_LDFLAGS += $(TARGET_FDO_CFLAGS)
endif

+
+####################################################
+## Add profiling flags if aprof is turned on
+####################################################
+ifeq ($(strip $(LOCAL_ENABLE_APROF)),true)
+ # -ffunction-sections and -fomit-frame-pointer are conflict with -pg
+ LOCAL_CFLAGS += -fno-omit-frame-pointer -fno-function-sections -pg
+ LOCAL_CPPFLAGS += -fno-omit-frame-pointer -fno-function-sections -pg
+endif
+
###########################################################
## Define PRIVATE_ variables from global vars
###########################################################
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index ee28f21..1048c8d 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -75,6 +75,7 @@ LOCAL_COPY_HEADERS:=
LOCAL_FORCE_STATIC_EXECUTABLE:=
LOCAL_ADDITIONAL_DEPENDENCIES:=
LOCAL_PRELINK_MODULE:=
+LOCAL_ENABLE_APROF:=
LOCAL_COMPRESS_MODULE_SYMBOLS:=
LOCAL_STRIP_MODULE:=
LOCAL_POST_PROCESS_COMMAND:=true
diff --git a/core/executable.mk b/core/executable.mk
index 3c73603..d4f7201 100644
--- a/core/executable.mk
+++ b/core/executable.mk
@@ -21,6 +21,19 @@ else
LOCAL_PRELINK_MODULE := true
endif

+
+####################################################
+## Add profiling libraries if aprof is turned
+####################################################
+ifeq ($(strip $(LOCAL_ENABLE_APROF)),true)
+ ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE), true)
+ LOCAL_STATIC_LIBRARIES += libaprof libaprof-static libc libcutils
+ else
+ LOCAL_SHARED_LIBRARIES += libaprof libaprof-stubs libc
+ endif
+ LOCAL_WHOLE_STATIC_LIBRARIES += libaprof-aux
+endif
+
include $(BUILD_SYSTEM)/dynamic_binary.mk

ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
diff --git a/core/shared_library.mk b/core/shared_library.mk
index 77d253f..9fe5bda 100644
--- a/core/shared_library.mk
+++ b/core/shared_library.mk
@@ -20,6 +20,13 @@ ifneq ($(strip $(OVERRIDE_BUILT_MODULE_PATH)),)
$(error $(LOCAL_PATH): Illegal use of OVERRIDE_BUILT_MODULE_PATH)
endif

+####################################################
+## Add profiling libraries if aprof is turned
+####################################################
+ifeq ($(strip $(LOCAL_ENABLE_APROF)),true)
+ LOCAL_SHARED_LIBRARIES += libaprof libaprof-stubs
+endif
+
# Put the built targets of all shared libraries in a common directory
# to simplify the link line.
OVERRIDE_BUILT_MODULE_PATH := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)
diff --git a/core/static_library.mk b/core/static_library.mk
index 4ff5a34..315c497 100644
--- a/core/static_library.mk
+++ b/core/static_library.mk
@@ -15,6 +15,13 @@ LOCAL_MODULE_SUFFIX := .a
endif
LOCAL_UNINSTALLABLE_MODULE := true

+####################################################
+## Add profiling libraries if aprof is turned
+####################################################
+ifeq ($(strip $(LOCAL_ENABLE_APROF)),true)
+ LOCAL_WHOLE_STATIC_LIBRARIES += libaprof
+endif
+
include $(BUILD_SYSTEM)/binary.mk

ifeq ($(LOCAL_RAW_STATIC_LIBRARY),true)
--
1.7.7.3

Jim Huang

unread,
Dec 1, 2011, 8:14:39 PM12/1/11
to 0xlab...@googlegroups.com
2011/12/2 Kito Cheng <ki...@0xlab.org>:

>  tools/aprof/Android.mk          |   40 ++++++++++
>  tools/aprof/Aprof.cpp           |  113 +++++++++++++++++++++++++++
>  tools/aprof/Aprof.h             |   34 ++++++++
>  tools/aprof/Edge.cpp            |   10 +++
>  tools/aprof/Edge.h              |   22 +++++
[...]

My questions:
(1) Why are tools/aprof/{Edge.cpp,Profiles.cpp not built at the moment?
(2) Can you add the proper copyright notice in each file?

> --- /dev/null
> +++ b/tools/aprof/Android.mk
[...]


> +LOCAL_SRC_FILES := \
> +    main.cpp \
> +       Aprof.cpp \
> +       Symbol.cpp \
> +       SymbolTable.cpp \
> +       Image.cpp \
> +       ImageCollection.cpp \
> +       Options.cpp
> +#      Edge.cpp \
> +#      Profiles.cpp \

[...]

Kito Cheng

unread,
Dec 2, 2011, 1:47:13 AM12/2/11
to 0xlab...@googlegroups.com
> My questions:
> (1) Why are tools/aprof/{Edge.cpp,Profiles.cpp not built at the moment?
oop, they should be removed...I will clean up it.

> (2) Can you add the proper copyright notice in each file?

So..what kind of copyright notice should I add ?

/*
* Copyright 2011 The Android Open Source Project
*/

or

/*
* Copyright 2011 0xlab
*/

by the way, aprof in build is GPL since it's link to libelf in elfutils.

Jim Huang

unread,
Dec 2, 2011, 4:14:29 AM12/2/11
to 0xlab...@googlegroups.com
2011/12/2 Kito Cheng <ki...@0xlab.org>:

>> (2) Can you add the proper copyright notice in each file?
>
> So..what kind of copyright notice should I add ?
>
> /*
>  * Copyright 2011 The Android Open Source Project
>  */

IMHO, use this one and apply GPL terms.

Thanks,
Jim Huang (jserv)
http://0xlab.org/

Reply all
Reply to author
Forward
0 new messages