diff --git a/tools/elftree/Android.mk b/tools/elftree/Android.mk deleted file mode 100644 index 7e84f989f..000000000 --- a/tools/elftree/Android.mk +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2010 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH := $(call my-dir) - -ifeq ($(HOST_OS),linux) - -include $(CLEAR_VARS) -LOCAL_MODULE := elftree -LOCAL_SRC_FILES := elftree.c -LOCAL_STATIC_LIBRARIES := libelf -include $(BUILD_HOST_EXECUTABLE) - -endif diff --git a/tools/elftree/MODULE_LICENSE_APACHE2 b/tools/elftree/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29bb..000000000 diff --git a/tools/elftree/elftree.c b/tools/elftree/elftree.c deleted file mode 100644 index d7ded13f4..000000000 --- a/tools/elftree/elftree.c +++ /dev/null @@ -1,328 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#define PATH_MAX 256 - -static enum { HIDE_DUPS, PRUNE_DUPS, SHOW_DUPS } dup_mode; -static char *root_name; - -static void app_err(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - - fprintf(stderr, "\n"); -} - -static void unix_err(const char *fmt, ...) -{ - va_list ap; - int errsv; - - errsv = errno; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - - fprintf(stderr, ": %s\n", strerror(errsv)); -} - -static void elf_err(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - - fprintf(stderr, ": %s\n", elf_errmsg(-1)); -} - -struct seen { - char *name; - struct seen *next; -}; - -struct tree_state { - int level; - struct seen *seen; -}; - -static int seen(struct tree_state *t, char *name) -{ - struct seen *s; - - for (s = t->seen; s; s = s->next) { - if (!strcmp(s->name, name)) - return 1; - } - - return 0; -} - -static void see(struct tree_state *t, char *name) -{ - struct seen *s = malloc(sizeof(*s)); - s->name = malloc(strlen(name) + 1); - strcpy(s->name, name); - s->next = t->seen; - t->seen = s; -} - -char *indent_str = " "; - -static void indent(struct tree_state *t) -{ - int i; - - for (i = 0; i < t->level; i++) - printf("%s", indent_str); -} - -struct search_dir { - char *path; - struct search_dir *next; -} *dirs = NULL; - -static void add_search_dir(char *path) -{ - struct search_dir *dir = malloc(sizeof(*dir)); - dir->path = malloc(strlen(path) + 1); - strcpy(dir->path, path); - dir->next = dirs; - dirs = dir; -} - -struct file_state { - struct tree_state *t; - Elf *e; - Elf_Data *strtab_data; -}; - -static Elf_Scn *find_scn(struct file_state *f, GElf_Word sht, Elf_Scn *scn, GElf_Shdr *shdr_out) -{ - while ((scn = elf_nextscn(f->e, scn))) { - if (!gelf_getshdr(scn, shdr_out)) - continue; - - if (shdr_out->sh_type == sht) - break; - } - - return scn; -} - -struct dyn_state { - struct file_state *f; - Elf_Data *dyn_data; - int count; -}; - -static int find_dyn(struct dyn_state *d, GElf_Sxword tag, GElf_Dyn *dyn_out) -{ - int i; - - for (i = 0; i < d->count; i++) { - if (!gelf_getdyn(d->dyn_data, i, dyn_out)) - continue; - - if (dyn_out->d_tag == tag) - return 0; - } - - return -1; -} - -static int dump_file(struct tree_state *t, char *name, char *path); - -static int dump_needed(struct tree_state *t, char *name) -{ - struct search_dir *dir; - char path[PATH_MAX]; - int fd; - - t->level++; - - for (dir = dirs; dir; dir = dir->next) { - snprintf(path, PATH_MAX, "%s/%s", dir->path, name); - fd = open(path, O_RDONLY); - if (fd >= 0) { - close(fd); - dump_file(t, name, path); - t->level--; - return 0; - } - } - - app_err("Couldn't resolve dependency \"%s\".", name); - t->level--; - return -1; -} - -static int dump_dynamic(struct file_state *f, Elf_Scn *scn, GElf_Shdr *shdr) -{ - struct dyn_state d; - GElf_Dyn needed_dyn; - char *needed_name; - int i; - - d.f = f; - d.dyn_data = elf_getdata(scn, NULL); - if (!d.dyn_data) { - elf_err("elf_getdata failed"); - return -1; - } - d.count = shdr->sh_size / shdr->sh_entsize; - - for (i = 0; i < d.count; i++) { - if (!gelf_getdyn(d.dyn_data, i, &needed_dyn)) - continue; - - if (needed_dyn.d_tag != DT_NEEDED) - continue; - - needed_name = (char *)f->strtab_data->d_buf - + needed_dyn.d_un.d_val; - - dump_needed(f->t, needed_name); - } - - return 0; -} - -static int dump_file(struct tree_state *t, char *name, char *file) -{ - struct file_state f; - int fd; - Elf_Scn *scn; - GElf_Shdr shdr; - - if ((dup_mode == HIDE_DUPS) && seen(t, name)) - return 0; - - indent(t); printf("%s", name); - - if ((dup_mode == PRUNE_DUPS) && seen(t, name)) { - printf("...\n"); - return 0; - } else { - printf(":\n"); - } - - see(t, name); - - f.t = t; - - fd = open(file, O_RDONLY); - if (fd < 0) { - unix_err("open(%s) failed", file); - return -1; - } - - f.e = elf_begin(fd, ELF_C_READ, NULL); - if (!f.e) { - elf_err("elf_begin failed on %s", file); - return -1; - } - - scn = find_scn(&f, SHT_STRTAB, NULL, &shdr); - f.strtab_data = elf_getdata(scn, NULL); - if (!f.strtab_data) { - app_err("%s has no strtab section", file); - return -1; - } - - scn = NULL; - while ((scn = find_scn(&f, SHT_DYNAMIC, scn, &shdr))) { - dump_dynamic(&f, scn, &shdr); - } - - elf_end(f.e); - close(fd); - - return 0; -} - -static void usage(void) -{ - fprintf(stderr, "Usage: elftree [ -s | -h ] elf-file\n" - " -S Duplicate entire subtree when a duplicate is found\n" - " -P Show duplicates, but only include subtree once\n" - " -H Show each library at most once, even if duplicated\n" - " -h Show this help screen\n"); -} - -static int parse_args(int argc, char *argv[]) -{ - int i; - - for (i = 1; i < argc - 1; i++) { - if (!strcmp(argv[i], "-S")) { - dup_mode = SHOW_DUPS; - } else if (!strcmp(argv[i], "-P")) { - dup_mode = PRUNE_DUPS; - } else if (!strcmp(argv[i], "-H")) { - dup_mode = HIDE_DUPS; - } else if (!strcmp(argv[i], "-h")) { - usage(); - exit(0); - } else { - app_err("Unexpected argument \"%s\"!\n", argv[i]); - return -1; - } - } - - root_name = argv[argc - 1]; - - return 0; -} - -static void add_search_dirs(void) -{ - char *relpath; - char path[PATH_MAX]; - - relpath = getenv("ANDROID_PRODUCT_OUT"); - if (!relpath) { - app_err("Warning: ANDROID_PRODUCT_OUT not set; " - "using current directory.\n"); - relpath = "."; - } - - snprintf(path, PATH_MAX, "%s/%s", relpath, "system/lib"); - add_search_dir(path); -} - -int main(int argc, char *argv[]) -{ - struct tree_state t; - - if (argc < 2 || parse_args(argc, argv)) { - usage(); - exit(EXIT_FAILURE); - } - - if (elf_version(EV_CURRENT) == EV_NONE) { - elf_err("version mismatch"); - exit(EXIT_FAILURE); - } - - t.level = 0; - t.seen = NULL; - - add_search_dirs(); - - dump_file(&t, root_name, root_name); - - return 0; -}