summaryrefslogtreecommitdiffstats
path: root/tools/soslim
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:14 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:14 -0800
commit05806d7af62e07c6225b2e7103a1b115ecf6c9ad (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /tools/soslim
parent094268cf8cb37b9d904c8a1e3559cdd46d73cf66 (diff)
downloadbuild-05806d7af62e07c6225b2e7103a1b115ecf6c9ad.zip
build-05806d7af62e07c6225b2e7103a1b115ecf6c9ad.tar.gz
build-05806d7af62e07c6225b2e7103a1b115ecf6c9ad.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'tools/soslim')
-rw-r--r--tools/soslim/Android.mk49
-rw-r--r--tools/soslim/cmdline.c141
-rw-r--r--tools/soslim/cmdline.h16
-rw-r--r--tools/soslim/common.c35
-rw-r--r--tools/soslim/common.h49
-rw-r--r--tools/soslim/debug.c40
-rw-r--r--tools/soslim/debug.h88
-rw-r--r--tools/soslim/main.c360
-rw-r--r--tools/soslim/prelink_info.c106
-rw-r--r--tools/soslim/prelink_info.h9
-rw-r--r--tools/soslim/soslim.c528
-rw-r--r--tools/soslim/soslim.h32
-rw-r--r--tools/soslim/symfilter.c242
-rw-r--r--tools/soslim/symfilter.h50
14 files changed, 0 insertions, 1745 deletions
diff --git a/tools/soslim/Android.mk b/tools/soslim/Android.mk
deleted file mode 100644
index 60a860a..0000000
--- a/tools/soslim/Android.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2005 The Android Open Source Project
-#
-# Android.mk for soslim
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(TARGET_ARCH),arm)
-include $(CLEAR_VARS)
-
-LOCAL_LDLIBS += -ldl
-LOCAL_CFLAGS += -O2 -g
-LOCAL_CFLAGS += -fno-function-sections -fno-data-sections -fno-inline
-LOCAL_CFLAGS += -Wall -Wno-unused-function #-Werror
-LOCAL_CFLAGS += -DBIG_ENDIAN=1
-LOCAL_CFLAGS += -DARM_SPECIFIC_HACKS
-LOCAL_CFLAGS += -DSUPPORT_ANDROID_PRELINK_TAGS
-LOCAL_CFLAGS += -DDEBUG
-LOCAL_CFLAGS += -DSTRIP_STATIC_SYMBOLS
-LOCAL_CFLAGS += -DMOVE_SECTIONS_IN_RANGES
-
-ifeq ($(HOST_OS),windows)
-# Cygwin stat does not support ACCESSPERMS bitmask
-LOCAL_CFLAGS += -DACCESSPERMS=0777
-LOCAL_LDLIBS += -lintl
-endif
-
-LOCAL_SRC_FILES := \
- cmdline.c \
- common.c \
- debug.c \
- soslim.c \
- main.c \
- prelink_info.c \
- symfilter.c
-
-LOCAL_C_INCLUDES:= \
- $(LOCAL_PATH)/ \
- external/elfutils/lib/ \
- external/elfutils/libelf/ \
- external/elfutils/libebl/ \
- external/elfcopy/
-
-LOCAL_STATIC_LIBRARIES := libelfcopy libelf libebl libebl_arm #dl
-
-LOCAL_MODULE := soslim
-
-include $(BUILD_HOST_EXECUTABLE)
-endif #TARGET_ARCH==arm
diff --git a/tools/soslim/cmdline.c b/tools/soslim/cmdline.c
deleted file mode 100644
index c2d5e71..0000000
--- a/tools/soslim/cmdline.c
+++ /dev/null
@@ -1,141 +0,0 @@
-#include <debug.h>
-#include <cmdline.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <string.h>
-#include <ctype.h>
-
-extern char *optarg;
-extern int optind, opterr, optopt;
-
-static struct option long_options[] =
-{
- {"verbose", no_argument, 0, 'V'},
- {"quiet", no_argument, 0, 'Q'},
- {"shady", no_argument, 0, 'S'},
- {"print", no_argument, 0, 'p'},
- {"help", no_argument, 0, 'h'},
- {"outfile", required_argument, 0, 'o'},
- {"filter", required_argument, 0, 'f'},
- {"dry", no_argument, 0, 'n'},
- {"strip", no_argument, 0, 's'},
- {0, 0, 0, 0},
-};
-
-/* This array must parallel long_options[] */
-static
-const char *descriptions[sizeof(long_options)/sizeof(long_options[0])] = {
- "print verbose output",
- "suppress errors and warnings",
- "patch ABS symbols whose values coincide with section starts and ends",
- "print the symbol table (if specified, only -V is allowed)",
- "this help screen",
- "specify an output file (if not provided, input file is modified)",
- "specify a symbol-filter file",
- "dry run (perform all calculations but do not modify the ELF file)",
- "strip debug sections, if they are present"
-};
-
-void print_help(void)
-{
- fprintf(stdout,
- "invokation:\n"
- "\tsoslim file1 [file2 file3 ... fileN] [-Ldir1 -Ldir2 ... -LdirN] "
- "[-Vpn]\n"
- "or\n"
- "\tsoslim -h\n\n");
- fprintf(stdout, "options:\n");
- struct option *opt = long_options;
- const char **desc = descriptions;
- while (opt->name) {
- fprintf(stdout, "\t-%c/--%-15s %s\n",
- opt->val,
- opt->name,
- *desc);
- opt++;
- desc++;
- }
-}
-
-int get_options(int argc, char **argv,
- char **outfile,
- char **symsfile,
- int *print_symtab,
- int *verbose,
- int *quiet,
- int *shady,
- int *dry_run,
- int *strip_debug)
-{
- int c;
-
- ASSERT(outfile);
- *outfile = NULL;
- ASSERT(symsfile);
- *symsfile = NULL;
- ASSERT(print_symtab);
- *print_symtab = 0;
- ASSERT(verbose);
- *verbose = 0;
- ASSERT(quiet);
- *quiet = 0;
- ASSERT(shady);
- *shady = 0;
- ASSERT(dry_run);
- *dry_run = 0;
- ASSERT(strip_debug);
- *strip_debug = 0;
-
- while (1) {
- /* getopt_long stores the option index here. */
- int option_index = 0;
-
- c = getopt_long (argc, argv,
- "QVSphi:o:y:Y:f:ns",
- 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)
-
- 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 'p': *print_symtab = 1; break;
- case 'h': print_help(); exit(1); break;
- case 'V': *verbose = 1; break;
- case 'Q': *quiet = 1; break;
- case 'S': *shady = 1; break;
- case 'n': *dry_run = 1; break;
- case 's': *strip_debug = 1; break;
- case 'o': SET_STRING_OPTION(outfile); break;
- case 'f': SET_STRING_OPTION(symsfile); break;
- case '?':
- /* getopt_long already printed an error message. */
- break;
-
-#undef SET_STRING_OPTION
-
- default:
- FAILIF(1, "Unknown option");
- }
- }
-
- return optind;
-}
diff --git a/tools/soslim/cmdline.h b/tools/soslim/cmdline.h
deleted file mode 100644
index bfc431e..0000000
--- a/tools/soslim/cmdline.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef CMDLINE_H
-#define CMDLINE_H
-
-void print_help(void);
-
-int get_options(int argc, char **argv,
- char **outfile,
- char **symsfile,
- int *print_symtab,
- int *verbose,
- int *quiet,
- int *shady,
- int *dry_run,
- int *strip_debug);
-
-#endif/*CMDLINE_H*/
diff --git a/tools/soslim/common.c b/tools/soslim/common.c
deleted file mode 100644
index b90cf41..0000000
--- a/tools/soslim/common.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <stdlib.h>
-#include <common.h>
-#include <debug.h>
-
-void map_over_sections(Elf *elf,
- section_match_fn_t match,
- void *user_data)
-{
- Elf_Scn* section = NULL;
- while ((section = elf_nextscn(elf, section)) != NULL) {
- if (match(elf, section, user_data))
- return;
- }
-}
-
-void map_over_segments(Elf *elf,
- segment_match_fn_t match,
- void *user_data)
-{
- Elf32_Ehdr *ehdr;
- Elf32_Phdr *phdr;
- int index;
-
- ehdr = elf32_getehdr(elf);
- phdr = elf32_getphdr(elf);
-
- INFO("Scanning over %d program segments...\n",
- ehdr->e_phnum);
-
- for (index = ehdr->e_phnum; index; index--) {
- if (match(elf, phdr++, user_data))
- return;
- }
-}
-
diff --git a/tools/soslim/common.h b/tools/soslim/common.h
deleted file mode 100644
index dacf930..0000000
--- a/tools/soslim/common.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#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! */
-
-typedef int (*section_match_fn_t)(Elf *, Elf_Scn *, void *);
-void map_over_sections(Elf *, section_match_fn_t, void *);
-
-typedef int (*segment_match_fn_t)(Elf *, Elf32_Phdr *, void *);
-void map_over_segments(Elf *, segment_match_fn_t, void *);
-
-typedef struct {
- Elf_Scn *sect;
- Elf32_Shdr *hdr;
- Elf_Data *data;
- size_t index;
-} section_info_t;
-
-static inline void get_section_info(Elf_Scn *sect, section_info_t *info)
-{
- info->sect = sect;
- info->data = elf_getdata(sect, 0);
- info->hdr = elf32_getshdr(sect);
- info->index = elf_ndxscn(sect);
-}
-
-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/soslim/debug.c b/tools/soslim/debug.c
deleted file mode 100644
index b8365af..0000000
--- a/tools/soslim/debug.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include <debug.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#if 0
-
-#define NUM_COLS (32)
-
-int dump_hex_buffer(FILE *s, void *b, size_t len, size_t elsize) {
- int num_nonprintable = 0;
- int i, last;
- char *pchr = (char *)b;
- fputc('\n', s);
- for (i = last = 0; i < len; i++) {
- if (!elsize) {
- if (i && !(i % 4)) fprintf(s, " ");
- if (i && !(i % 8)) fprintf(s, " ");
- } else {
- if (i && !(i % elsize)) fprintf(s, " ");
- }
-
- if (i && !(i % NUM_COLS)) {
- while (last < i) {
- if (isprint(pchr[last]))
- fputc(pchr[last], s);
- else {
- fputc('.', s);
- num_nonprintable++;
- }
- last++;
- }
- fprintf(s, " (%d)\n", i);
- }
- fprintf(s, "%02x", (unsigned char)pchr[i]);
- }
- if (i && (i % NUM_COLS)) fputs("\n", s);
- return num_nonprintable;
-}
-
-#endif
diff --git a/tools/soslim/debug.h b/tools/soslim/debug.h
deleted file mode 100644
index e7a2f9a..0000000
--- a/tools/soslim/debug.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#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(x...) fprintf(stderr, ##x)
-
-#define INFO(x...) do { \
- extern int verbose_flag; \
- if(unlikely(verbose_flag)) \
- 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/soslim/main.c b/tools/soslim/main.c
deleted file mode 100644
index fa5a315..0000000
--- a/tools/soslim/main.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/* TODO:
- 1. check the ARM EABI version--this works for versions 1 and 2.
- 2. use a more-intelligent approach to finding the symbol table, symbol-string
- table, and the .dynamic section.
- 3. fix the determination of the host and ELF-file endianness
- 4. write the help screen
-*/
-
-#include <stdio.h>
-#include <common.h>
-#include <debug.h>
-#include <hash.h>
-#include <libelf.h>
-#include <elf.h>
-#include <gelf.h>
-#include <cmdline.h>
-#include <string.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <soslim.h>
-#include <symfilter.h>
-#ifdef SUPPORT_ANDROID_PRELINK_TAGS
-#include <prelink_info.h>
-#endif
-
-/* Flag set by --verbose. This variable is global as it is accessed by the
- macro INFO() in multiple compilation unites. */
-int verbose_flag = 0;
-/* Flag set by --quiet. This variable is global as it is accessed by the
- macro PRINT() in multiple compilation unites. */
-int quiet_flag = 0;
-static void print_dynamic_symbols(Elf *elf, const char *symtab_name);
-
-int main(int argc, char **argv)
-{
- int elf_fd = -1, newelf_fd = -1;
- Elf *elf = NULL, *newelf = NULL;
- char *infile = NULL;
- char *outfile = NULL;
- char *symsfile_name = NULL;
- int print_symtab = 0;
- int shady = 0;
- int dry_run = 0;
- int strip_debug = 0;
-
- /* Do not issue INFO() statements before you call get_options() to set
- the verbose flag as necessary.
- */
-
- int first = get_options(argc, argv,
- &outfile,
- &symsfile_name,
- &print_symtab,
- &verbose_flag,
- &quiet_flag,
- &shady,
- &dry_run,
- &strip_debug);
-
- if ((print_symtab && (first == argc)) ||
- (!print_symtab && first + 1 != argc)) {
- print_help();
- FAILIF(1, "You must specify an input ELF file!\n");
- }
- FAILIF(print_symtab && (outfile || symsfile_name || shady),
- "You cannot provide --print and --outfile, --filter options, or "
- "--shady simultaneously!\n");
- FAILIF(dry_run && outfile,
- "You cannot have a dry run and output a file at the same time.");
-
- /* Check to see whether the ELF library is current. */
- FAILIF (elf_version(EV_CURRENT) == EV_NONE, "libelf is out of date!\n");
-
- if (print_symtab) {
-
- while (first < argc) {
- infile = argv[first++];
-
- INFO("Opening %s...\n", infile);
- elf_fd = open(infile, O_RDONLY);
- FAILIF(elf_fd < 0, "open(%s): %s (%d)\n",
- infile,
- strerror(errno),
- errno);
- INFO("Calling elf_begin(%s)...\n", infile);
- elf = elf_begin(elf_fd, ELF_C_READ, NULL);
- FAILIF_LIBELF(elf == NULL, elf_begin);
-
- /* libelf can recognize COFF and A.OUT formats, but we handle only
- ELF. */
- FAILIF(elf_kind(elf) != ELF_K_ELF,
- "Input file %s is not in ELF format!\n",
- infile);
-
- /* Make sure this is a shared library or an executable. */
- {
- GElf_Ehdr elf_hdr;
- INFO("Making sure %s is a shared library or an executable.\n",
- infile);
- FAILIF_LIBELF(0 == gelf_getehdr(elf, &elf_hdr), gelf_getehdr);
- FAILIF(elf_hdr.e_type != ET_DYN &&
- elf_hdr.e_type != ET_EXEC,
- "%s must be a shared library or an executable "
- "(elf type is %d).\n",
- infile,
- elf_hdr.e_type);
- }
-
- print_dynamic_symbols(elf, infile);
-
- FAILIF_LIBELF(elf_end(elf), elf_end);
- FAILIF(close(elf_fd) < 0, "Could not close file %s: %s (%d)!\n",
- infile, strerror(errno), errno);
- }
- }
- else {
- int elf_fd = -1;
- Elf *elf = NULL;
- infile = argv[first];
-
- INFO("Opening %s...\n", infile);
- elf_fd = open(infile, ((outfile == NULL && dry_run == 0) ? O_RDWR : O_RDONLY));
- FAILIF(elf_fd < 0, "open(%s): %s (%d)\n",
- infile,
- strerror(errno),
- errno);
- INFO("Calling elf_begin(%s)...\n", infile);
- elf = elf_begin(elf_fd,
- ((outfile == NULL && dry_run == 0) ? ELF_C_RDWR : ELF_C_READ),
- NULL);
- FAILIF_LIBELF(elf == NULL, elf_begin);
-
- /* libelf can recognize COFF and A.OUT formats, but we handle only ELF. */
- FAILIF(elf_kind(elf) != ELF_K_ELF,
- "Input file %s is not in ELF format!\n",
- infile);
-
- /* We run a better check in adjust_elf() itself. It is permissible to call adjust_elf()
- on an executable if we are only stripping sections from the executable, not rearranging
- or moving sections.
- */
- if (0) {
- /* Make sure this is a shared library. */
- GElf_Ehdr elf_hdr;
- INFO("Making sure %s is a shared library...\n", infile);
- FAILIF_LIBELF(0 == gelf_getehdr(elf, &elf_hdr), gelf_getehdr);
- FAILIF(elf_hdr.e_type != ET_DYN,
- "%s must be a shared library (elf type is %d, expecting %d).\n",
- infile,
- elf_hdr.e_type,
- ET_DYN);
- }
-
- if (outfile != NULL) {
- ASSERT(!dry_run);
- struct stat st;
- FAILIF(fstat (elf_fd, &st) != 0,
- "Cannot stat input file %s: %s (%d)!\n",
- infile, strerror(errno), errno);
- newelf_fd = open (outfile, O_RDWR | O_CREAT | O_TRUNC,
- st.st_mode & ACCESSPERMS);
- FAILIF(newelf_fd < 0, "Cannot create file %s: %s (%d)!\n",
- outfile, strerror(errno), errno);
- INFO("Output file is [%s].\n", outfile);
- newelf = elf_begin(newelf_fd, ELF_C_WRITE_MMAP, NULL);
- } else {
- INFO("Modifying [%s] in-place.\n", infile);
- newelf = elf_clone(elf, ELF_C_EMPTY);
- }
-
- symfilter_t symfilter;
-
- symfilter.symbols_to_keep = NULL;
- symfilter.num_symbols_to_keep = 0;
- if (symsfile_name) {
- /* Make sure that the file is not empty. */
- struct stat s;
- FAILIF(stat(symsfile_name, &s) < 0,
- "Cannot stat file %s.\n", symsfile_name);
- if (s.st_size) {
- INFO("Building symbol filter.\n");
- build_symfilter(symsfile_name, elf, &symfilter, s.st_size);
- }
- else INFO("Not building symbol filter, filter file is empty.\n");
- }
-#ifdef SUPPORT_ANDROID_PRELINK_TAGS
- int prelinked = 0;
- int elf_little; /* valid if prelinked != 0 */
- long prelink_addr; /* valid if prelinked != 0 */
-#endif
- clone_elf(elf, newelf,
- infile, outfile,
- symfilter.symbols_to_keep,
- symfilter.num_symbols_to_keep,
- shady
-#ifdef SUPPORT_ANDROID_PRELINK_TAGS
- , &prelinked,
- &elf_little,
- &prelink_addr
-#endif
- ,
- true, /* rebuild the section-header-strings table */
- strip_debug,
- dry_run);
-
- if (symsfile_name && symfilter.symbols_to_keep != NULL) {
- destroy_symfilter(&symfilter);
- }
-
- if (outfile != NULL) INFO("Closing %s...\n", outfile);
- FAILIF_LIBELF(elf_end (newelf) != 0, elf_end);
- FAILIF(newelf_fd >= 0 && close(newelf_fd) < 0,
- "Could not close file %s: %s (%d)!\n",
- outfile, strerror(errno), errno);
-
- INFO("Closing %s...\n", infile);
- FAILIF_LIBELF(elf_end(elf), elf_end);
- FAILIF(close(elf_fd) < 0, "Could not close file %s: %s (%d)!\n",
- infile, strerror(errno), errno);
-
-#ifdef SUPPORT_ANDROID_PRELINK_TAGS
- if (prelinked) {
- INFO("File is prelinked, putting prelink TAG back in place.\n");
- setup_prelink_info(outfile != NULL ? outfile : infile,
- elf_little,
- prelink_addr);
- }
-#endif
- }
-
- FREEIF(outfile);
- return 0;
-}
-
-static void print_dynamic_symbols(Elf *elf, const char *file)
-{
- Elf_Scn *scn = NULL;
- GElf_Shdr shdr;
-
- GElf_Ehdr ehdr;
- 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);
- if (SHT_DYNSYM == shdr.sh_type) {
- /* This failure is too restrictive. There is no reason why
- the symbol table couldn't be called something else, but
- there is a standard name, and chances are that if we don't
- see it, there's something wrong.
- */
- size_t shstrndx;
- FAILIF_LIBELF(elf_getshstrndx(elf, &shstrndx) < 0,
- elf_getshstrndx);
- /* Now print the symbols. */
- {
- Elf_Data *symdata;
- size_t elsize;
- symdata = elf_getdata (scn, NULL); /* get the symbol data */
- FAILIF_LIBELF(NULL == symdata, elf_getdata);
- /* Get the number of section. We need to compare agains this
- value for symbols that have special info in their section
- references */
- size_t shnum;
- FAILIF_LIBELF(elf_getshnum (elf, &shnum) < 0, elf_getshnum);
- /* Retrieve the size of a symbol entry */
- elsize = gelf_fsize(elf, ELF_T_SYM, 1, ehdr.e_version);
-
- size_t index;
- for (index = 0; index < symdata->d_size / elsize; index++) {
- 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);
- /* Print the symbol. */
- char bind = '?';
- switch(ELF32_ST_BIND(sym->st_info))
- {
- case STB_LOCAL: bind = 'l'; break;
- case STB_GLOBAL: bind = 'g'; break;
- case STB_WEAK: bind = 'w'; break;
- default: break;
- }
- char type = '?';
- switch(ELF32_ST_TYPE(sym->st_info))
- {
- case STT_NOTYPE: /* Symbol type is unspecified */
- type = '?';
- break;
- case STT_OBJECT: /* Symbol is a data object */
- type = 'o';
- break;
- case STT_FUNC: /* Symbol is a code object */
- type = 'f';
- break;
- case STT_SECTION:/* Symbol associated with a section */
- type = 's';
- break;
- case STT_FILE: /* Symbol's name is file name */
- type = 'f';
- break;
- case STT_COMMON: /* Symbol is a common data object */
- type = 'c';
- break;
- case STT_TLS: /* Symbol is thread-local data object*/
- type = 't';
- break;
- }
- {
- int till_lineno;
- int lineno;
- const char *section_name = "(unknown)";
- FAILIF(sym->st_shndx == SHN_XINDEX,
- "Can't handle symbol's st_shndx == SHN_XINDEX!\n");
- if (sym->st_shndx != SHN_UNDEF &&
- sym->st_shndx < shnum) {
- Elf_Scn *symscn = elf_getscn(elf, sym->st_shndx);
- FAILIF_LIBELF(NULL == symscn, elf_getscn);
- GElf_Shdr symscn_shdr;
- FAILIF_LIBELF(NULL == gelf_getshdr(symscn,
- &symscn_shdr),
- gelf_getshdr);
- section_name = elf_strptr(elf, shstrndx,
- symscn_shdr.sh_name);
- }
- else if (sym->st_shndx == SHN_ABS) {
- section_name = "SHN_ABS";
- }
- else if (sym->st_shndx == SHN_COMMON) {
- section_name = "SHN_COMMON";
- }
- else if (sym->st_shndx == SHN_UNDEF) {
- section_name = "(undefined)";
- }
- /* value size binding type section symname */
- PRINT("%-15s %8d: %08llx %08llx %c%c %5d %n%s%n",
- file,
- index,
- sym->st_value, sym->st_size, bind, type,
- sym->st_shndx,
- &till_lineno,
- section_name,
- &lineno);
- lineno -= till_lineno;
- /* Create padding for section names of 15 chars.
- This limit is somewhat arbitratry. */
- while (lineno++ < 15) PRINT(" ");
- PRINT("(%d) %s\n",
- sym->st_name,
- elf_strptr(elf, shdr.sh_link, sym->st_name));
- }
- }
- }
- } /* if (shdr.sh_type = SHT_DYNSYM) */
- } /* while ((scn = elf_nextscn (elf, scn)) != NULL) */
-}
diff --git a/tools/soslim/prelink_info.c b/tools/soslim/prelink_info.c
deleted file mode 100644
index 36516b1..0000000
--- a/tools/soslim/prelink_info.c
+++ /dev/null
@@ -1,106 +0,0 @@
-#ifdef SUPPORT_ANDROID_PRELINK_TAGS
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#include <prelink_info.h>
-#include <debug.h>
-#include <common.h>
-
-typedef struct {
- uint32_t mmap_addr;
- char tag[4]; /* 'P', 'R', 'E', ' ' */
-} prelink_info_t __attribute__((packed));
-
-static inline void set_prelink(long *prelink_addr,
- int elf_little,
- prelink_info_t *info)
-{
- FAILIF(sizeof(prelink_info_t) != 8, "Unexpected sizeof(prelink_info_t) == %d!\n", sizeof(prelink_info_t));
- if (prelink_addr) {
- if (!(elf_little ^ is_host_little())) {
- /* Same endianness */
- *prelink_addr = info->mmap_addr;
- }
- else {
- /* Different endianness */
- *prelink_addr = switch_endianness(info->mmap_addr);
- }
- }
-}
-
-int check_prelinked(const char *fname, int elf_little, long *prelink_addr)
-{
- FAILIF(sizeof(prelink_info_t) != 8, "Unexpected sizeof(prelink_info_t) == %d!\n", sizeof(prelink_info_t));
- int fd = open(fname, O_RDONLY);
- FAILIF(fd < 0, "open(%s, O_RDONLY): %s (%d)!\n",
- fname, strerror(errno), errno);
- off_t end = lseek(fd, 0, SEEK_END);
-
- int nr = sizeof(prelink_info_t);
-
- off_t sz = lseek(fd, -nr, SEEK_CUR);
- ASSERT((long)(end - sz) == (long)nr);
- FAILIF(sz == (off_t)-1,
- "lseek(%d, 0, SEEK_END): %s (%d)!\n",
- fd, strerror(errno), errno);
-
- prelink_info_t info;
- int num_read = read(fd, &info, nr);
- FAILIF(num_read < 0,
- "read(%d, &info, sizeof(prelink_info_t)): %s (%d)!\n",
- fd, strerror(errno), errno);
- FAILIF(num_read != sizeof(info),
- "read(%d, &info, sizeof(prelink_info_t)): did not read %d bytes as "
- "expected (read %d)!\n",
- fd, sizeof(info), num_read);
-
- int prelinked = 0;
- if (!strncmp(info.tag, "PRE ", 4)) {
- set_prelink(prelink_addr, elf_little, &info);
- prelinked = 1;
- }
- FAILIF(close(fd) < 0, "close(%d): %s (%d)!\n", fd, strerror(errno), errno);
- return prelinked;
-}
-
-void setup_prelink_info(const char *fname, int elf_little, long base)
-{
- FAILIF(sizeof(prelink_info_t) != 8, "Unexpected sizeof(prelink_info_t) == %d!\n", sizeof(prelink_info_t));
- int fd = open(fname, O_WRONLY);
- FAILIF(fd < 0,
- "open(%s, O_WRONLY): %s (%d)\n" ,
- fname, strerror(errno), errno);
- prelink_info_t info;
- off_t sz = lseek(fd, 0, SEEK_END);
- FAILIF(sz == (off_t)-1,
- "lseek(%d, 0, SEEK_END): %s (%d)!\n",
- fd, strerror(errno), errno);
-
- if (!(elf_little ^ is_host_little())) {
- /* Same endianness */
- INFO("Host and ELF file [%s] have same endianness.\n", fname);
- info.mmap_addr = base;
- }
- else {
- /* Different endianness */
- INFO("Host and ELF file [%s] have different endianness.\n", fname);
- info.mmap_addr = switch_endianness(base);
- }
- strncpy(info.tag, "PRE ", 4);
-
- int num_written = write(fd, &info, sizeof(info));
- FAILIF(num_written < 0,
- "write(%d, &info, sizeof(info)): %s (%d)\n",
- fd, strerror(errno), errno);
- FAILIF(sizeof(info) != num_written,
- "Could not write %d bytes (wrote only %d bytes) as expected!\n",
- sizeof(info), num_written);
- FAILIF(close(fd) < 0, "close(%d): %s (%d)!\n", fd, strerror(errno), errno);
-}
-
-#endif /*SUPPORT_ANDROID_PRELINK_TAGS*/
diff --git a/tools/soslim/prelink_info.h b/tools/soslim/prelink_info.h
deleted file mode 100644
index e2787cb..0000000
--- a/tools/soslim/prelink_info.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef PRELINK_INFO_H
-#define PRELINK_INFO_H
-#ifdef SUPPORT_ANDROID_PRELINK_TAGS
-
-int check_prelinked(const char *fname, int elf_little, long *prelink_addr);
-void setup_prelink_info(const char *fname, int elf_little, long base);
-
-#endif
-#endif/*PRELINK_INFO_H*/
diff --git a/tools/soslim/soslim.c b/tools/soslim/soslim.c
deleted file mode 100644
index 4e59c24..0000000
--- a/tools/soslim/soslim.c
+++ /dev/null
@@ -1,528 +0,0 @@
-#include <stdio.h>
-//#include <common.h>
-#include <debug.h>
-#include <libelf.h>
-#include <libebl.h>
-#include <libebl_arm.h>
-#include <elf.h>
-#include <gelf.h>
-#include <string.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#ifdef SUPPORT_ANDROID_PRELINK_TAGS
-#include <prelink_info.h>
-#endif
-
-#include <elfcopy.h>
-
-void clone_elf(Elf *elf, Elf *newelf,
- const char *elf_name,
- const char *newelf_name,
- bool *sym_filter, int num_symbols,
- int shady
-#ifdef SUPPORT_ANDROID_PRELINK_TAGS
- , int *prelinked,
- int *elf_little,
- long *prelink_addr
-#endif
- , bool rebuild_shstrtab,
- bool strip_debug,
- bool dry_run)
-{
- GElf_Ehdr ehdr_mem, *ehdr; /* store ELF header of original library */
- size_t shstrndx; /* section-strings-section index */
- size_t shnum; /* number of sections in the original file */
- /* string table for section headers in new file */
- struct Ebl_Strtab *shst = NULL;
- int dynamic_idx = -1; /* index in shdr_info[] of .dynamic section */
- int dynsym_idx = -1; /* index in shdr_info[] of dynamic symbol table
- section */
-
- int cnt; /* general-purpose counter */
- /* This flag is true when at least one section is dropped or when the
- relative order of sections has changed, so that section indices in
- the resulting file will be different from those in the original. */
- bool sections_dropped_or_rearranged;
- Elf_Scn *scn; /* general-purpose section */
- size_t idx; /* general-purporse section index */
-
- shdr_info_t *shdr_info = NULL;
- int shdr_info_len = 0;
- GElf_Phdr *phdr_info = NULL;
-
- /* Get the information from the old file. */
- ehdr = gelf_getehdr (elf, &ehdr_mem);
- FAILIF_LIBELF(NULL == ehdr, gelf_getehdr);
-
- /* Create new program header for the elf file */
- FAILIF(gelf_newehdr (newelf, gelf_getclass (elf)) == 0 ||
- (ehdr->e_type != ET_REL && gelf_newphdr (newelf,
- ehdr->e_phnum) == 0),
- "Cannot create new file: %s", elf_errmsg (-1));
-
-#ifdef SUPPORT_ANDROID_PRELINK_TAGS
- ASSERT(prelinked);
- ASSERT(prelink_addr);
- ASSERT(elf_little);
- *elf_little = (ehdr->e_ident[EI_DATA] == ELFDATA2LSB);
- *prelinked = check_prelinked(elf_name, *elf_little, prelink_addr);
-#endif
-
- INFO("\n\nCALCULATING MODIFICATIONS\n\n");
-
- /* Copy out the old program header: notice that if the ELF file does not
- have a program header, this loop won't execute.
- */
- INFO("Copying ELF program header...\n");
- phdr_info = (GElf_Phdr *)CALLOC(ehdr->e_phnum, sizeof(GElf_Phdr));
- for (cnt = 0; cnt < ehdr->e_phnum; ++cnt) {
- INFO("\tRetrieving entry %d\n", cnt);
- FAILIF_LIBELF(NULL == gelf_getphdr(elf, cnt, phdr_info + cnt),
- gelf_getphdr);
- /* -- we update the header at the end
- FAILIF_LIBELF(gelf_update_phdr (newelf, cnt, phdr_info + cnt) == 0,
- gelf_update_phdr);
- */
- }
-
- /* Get the section-header strings section. This section contains the
- strings used to name the other sections. */
- FAILIF_LIBELF(elf_getshstrndx(elf, &shstrndx) < 0, elf_getshstrndx);
-
- /* Get the number of sections. */
- FAILIF_LIBELF(elf_getshnum (elf, &shnum) < 0, elf_getshnum);
- INFO("Original ELF file has %d sections.\n", shnum);
-
- /* Allocate the section-header-info buffer. We allocate one more entry
- for the section-strings section because we regenerate that one and
- place it at the very end of the file. Note that just because we create
- an extra entry in the shdr_info array, it does not mean that we create
- one more section the header. We just mark the old section for removal
- and create one as the last section.
- */
- INFO("Allocating section-header info structure (%d) bytes...\n",
- shnum*sizeof (shdr_info_t));
- shdr_info_len = rebuild_shstrtab ? shnum + 1 : shnum;
- shdr_info = (shdr_info_t *)CALLOC(shdr_info_len, sizeof (shdr_info_t));
-
- /* Iterate over all the sections and initialize the internal section-info
- array...
- */
- INFO("Initializing section-header info structure...\n");
- /* Gather information about the sections in this file. */
- scn = NULL;
- cnt = 1;
- while ((scn = elf_nextscn (elf, scn)) != NULL) {
- ASSERT(elf_ndxscn(scn) == cnt);
- shdr_info[cnt].scn = scn;
- FAILIF_LIBELF(NULL == gelf_getshdr(scn, &shdr_info[cnt].shdr),
- gelf_getshdr);
-
- /* Get the name of the section. */
- shdr_info[cnt].name = elf_strptr (elf, shstrndx,
- shdr_info[cnt].shdr.sh_name);
-
- INFO("\tname: %s\n", shdr_info[cnt].name);
- FAILIF(shdr_info[cnt].name == NULL,
- "Malformed file: section %d name is null\n",
- cnt);
-
- /* Mark them as present but not yet investigated. By "investigating"
- sections, we mean that we check to see if by stripping other
- sections, the sections under investigation will be compromised. For
- example, if we are removing a section of code, then we want to make
- sure that the symbol table does not contain symbols that refer to
- this code, so we investigate the symbol table. If we do find such
- symbols, we will not strip the code section.
- */
- shdr_info[cnt].idx = 1;
-
- /* Remember the shdr.sh_link value. We need to remember this value
- for those sections that refer to other sections. For example,
- we need to remember it for relocation-entry sections, because if
- we modify the symbol table that a relocation-entry section is
- relative to, then we need to patch the relocation section. By the
- time we get to deciding whether we need to patch the relocation
- section, we will have overwritten its header's sh_link field with
- a new value.
- */
- shdr_info[cnt].old_shdr = shdr_info[cnt].shdr;
- INFO("\t\toriginal sh_link: %08d\n", shdr_info[cnt].old_shdr.sh_link);
- INFO("\t\toriginal sh_addr: %lld\n", shdr_info[cnt].old_shdr.sh_addr);
- INFO("\t\toriginal sh_offset: %lld\n",
- shdr_info[cnt].old_shdr.sh_offset);
- INFO("\t\toriginal sh_size: %lld\n", shdr_info[cnt].old_shdr.sh_size);
-
- if (shdr_info[cnt].shdr.sh_type == SHT_DYNAMIC) {
- INFO("\t\tthis is the SHT_DYNAMIC section [%s] at index %d\n",
- shdr_info[cnt].name,
- cnt);
- dynamic_idx = cnt;
- }
- else if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM) {
- INFO("\t\tthis is the SHT_DYNSYM section [%s] at index %d\n",
- shdr_info[cnt].name,
- cnt);
- dynsym_idx = cnt;
- }
-
- FAILIF(shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX,
- "Cannot handle sh_type SHT_SYMTAB_SHNDX!\n");
- FAILIF(shdr_info[cnt].shdr.sh_type == SHT_GROUP,
- "Cannot handle sh_type SHT_GROUP!\n");
- FAILIF(shdr_info[cnt].shdr.sh_type == SHT_GNU_versym,
- "Cannot handle sh_type SHT_GNU_versym!\n");
-
- /* Increment the counter. */
- ++cnt;
- } /* while */
-
- /* Get the EBL handling. */
- Ebl *ebl = ebl_openbackend (elf);
- FAILIF_LIBELF(NULL == ebl, ebl_openbackend);
- FAILIF_LIBELF(0 != arm_init(elf, ehdr->e_machine, ebl, sizeof(Ebl)),
- arm_init);
-
- if (strip_debug) {
-
- /* This will actually strip more than just sections. It will strip
- anything not essential to running the image.
- */
-
- INFO("Finding debug sections to strip.\n");
-
- /* Now determine which sections can go away. The general rule is that
- all sections which are not used at runtime are stripped out. But
- there are a few exceptions:
-
- - special sections named ".comment" and ".note" are kept
- - OS or architecture specific sections are kept since we might not
- know how to handle them
- - if a section is referred to from a section which is not removed
- in the sh_link or sh_info element it cannot be removed either
- */
- for (cnt = 1; cnt < shnum; ++cnt) {
- /* Check whether the section can be removed. */
- if (SECTION_STRIP_P (ebl, elf, ehdr, &shdr_info[cnt].shdr,
- shdr_info[cnt].name,
- 1, /* remove .comment sections */
- 1 /* remove all debug sections */) ||
- /* The macro above is broken--check for .comment explicitly */
- !strcmp(".comment", shdr_info[cnt].name)
-#ifdef ARM_SPECIFIC_HACKS
- ||
- /* We ignore this section, that's why we can remove it. */
- !strcmp(".stack", shdr_info[cnt].name)
-#endif
- )
- {
- /* For now assume this section will be removed. */
- INFO("Section [%s] will be stripped from image.\n",
- shdr_info[cnt].name);
- shdr_info[cnt].idx = 0;
- }
-#ifdef STRIP_STATIC_SYMBOLS
- else if (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB) {
- /* Mark the static symbol table for removal */
- INFO("Section [%s] (static symbol table) will be stripped from image.\n",
- shdr_info[cnt].name);
- shdr_info[cnt].idx = 0;
- if (shdr_info[shdr_info[cnt].shdr.sh_link].shdr.sh_type ==
- SHT_STRTAB)
- {
- /* Mark the symbol table's string table for removal. */
- INFO("Section [%s] (static symbol-string table) will be stripped from image.\n",
- shdr_info[cnt].name);
- shdr_info[shdr_info[cnt].shdr.sh_link].idx = 0;
- }
- else {
- ERROR("Expecting the sh_link field of a symbol table to point to"
- " associated symbol-strings table! This is not mandated by"
- " the standard, but is a common practice and the only way "
- " to know for sure which strings table corresponds to which"
- " symbol table!\n");
- }
- }
-#endif
- }
-
- /* Mark the SHT_NULL section as handled. */
- shdr_info[0].idx = 2;
-
- /* Handle exceptions: section groups and cross-references. We might have
- to repeat this a few times since the resetting of the flag might
- propagate.
- */
- int exceptions_pass = 0;
- bool changes;
- do {
- changes = false;
- INFO("\nHandling exceptions, pass %d\n\n", exceptions_pass++);
- for (cnt = 1; cnt < shnum; ++cnt) {
- if (shdr_info[cnt].idx == 0) {
- /* If a relocation section is marked as being removed but the
- section it is relocating is not, then do not remove the
- relocation section.
- */
- if ((shdr_info[cnt].shdr.sh_type == SHT_REL
- || shdr_info[cnt].shdr.sh_type == SHT_RELA)
- && shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0) {
- PRINT("\tSection [%s] will not be removed because the "
- "section it is relocating (%s) stays.\n",
- shdr_info[cnt].name,
- shdr_info[shdr_info[cnt].shdr.sh_info].name);
- }
- }
- if (shdr_info[cnt].idx == 1) {
- INFO("Processing section [%s]...\n", shdr_info[cnt].name);
-
- /* The content of symbol tables we don't remove must not
- reference any section which we do remove. Otherwise
- we cannot remove the referred section.
- */
- if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM ||
- shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)
- {
- Elf_Data *symdata;
- size_t elsize;
-
- INFO("\tSection [%s] is a symbol table that's not being"
- " removed.\n\tChecking to make sure that no symbols"
- " refer to sections that are being removed.\n",
- shdr_info[cnt].name);
-
- /* Make sure the data is loaded. */
- symdata = elf_getdata (shdr_info[cnt].scn, NULL);
- FAILIF_LIBELF(NULL == symdata, elf_getdata);
-
- /* Go through all symbols and make sure the section they
- reference is not removed. */
- elsize = gelf_fsize (elf, ELF_T_SYM, 1, ehdr->e_version);
-
- /* Check the length of the dynamic-symbol filter. */
- FAILIF(sym_filter != NULL &&
- num_symbols != symdata->d_size / elsize,
- "Length of dynsym filter (%d) must equal the number"
- " of dynamic symbols (%d)!\n",
- num_symbols,
- symdata->d_size / elsize);
-
- size_t inner;
- for (inner = 0;
- inner < symdata->d_size / elsize;
- ++inner)
- {
- GElf_Sym sym_mem;
- GElf_Sym *sym;
- size_t scnidx;
-
- sym = gelf_getsymshndx (symdata, NULL,
- inner, &sym_mem, NULL);
- FAILIF_LIBELF(sym == NULL, gelf_getsymshndx);
-
- scnidx = sym->st_shndx;
- FAILIF(scnidx == SHN_XINDEX,
- "Can't handle SHN_XINDEX!\n");
- if (scnidx == SHN_UNDEF ||
- scnidx >= shnum ||
- (scnidx >= SHN_LORESERVE &&
- scnidx <= SHN_HIRESERVE) ||
- GELF_ST_TYPE (sym->st_info) == STT_SECTION)
- {
- continue;
- }
-
- /* If the symbol is going to be thrown and it is a
- global or weak symbol that is defined (not imported),
- then continue. Since the symbol is going away, we
- do not care whether it refers to a section that is
- also going away.
- */
- if (sym_filter && !sym_filter[inner])
- {
- bool global_or_weak =
- ELF32_ST_BIND(sym->st_info) == STB_GLOBAL ||
- ELF32_ST_BIND(sym->st_info) == STB_WEAK;
- if (!global_or_weak && sym->st_shndx != SHN_UNDEF)
- continue;
- }
-
- /* -- far too much output
- INFO("\t\t\tSymbol [%s] (%d)\n",
- elf_strptr(elf,
- shdr_info[cnt].shdr.sh_link,
- sym->st_name),
- shdr_info[cnt].shdr.sh_info);
- */
-
- if (shdr_info[scnidx].idx == 0)
- {
- PRINT("\t\t\tSymbol [%s] refers to section [%s], "
- "which is being removed. Will keep that "
- "section.\n",
- elf_strptr(elf,
- shdr_info[cnt].shdr.sh_link,
- sym->st_name),
- shdr_info[scnidx].name);
- /* Mark this section as used. */
- shdr_info[scnidx].idx = 1;
- changes |= scnidx < cnt;
- }
- } /* for each symbol */
- } /* section type is SHT_DYNSYM or SHT_SYMTAB */
- /* Cross referencing happens:
- - for the cases the ELF specification says. That are
- + SHT_DYNAMIC in sh_link to string table
- + SHT_HASH in sh_link to symbol table
- + SHT_REL and SHT_RELA in sh_link to symbol table
- + SHT_SYMTAB and SHT_DYNSYM in sh_link to string table
- + SHT_GROUP in sh_link to symbol table
- + SHT_SYMTAB_SHNDX in sh_link to symbol table
- Other (OS or architecture-specific) sections might as
- well use this field so we process it unconditionally.
- - references inside section groups
- - specially marked references in sh_info if the SHF_INFO_LINK
- flag is set
- */
-
- if (shdr_info[shdr_info[cnt].shdr.sh_link].idx == 0) {
- shdr_info[shdr_info[cnt].shdr.sh_link].idx = 1;
- changes |= shdr_info[cnt].shdr.sh_link < cnt;
- }
-
- /* Handle references through sh_info. */
- if (SH_INFO_LINK_P (&shdr_info[cnt].shdr) &&
- shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0) {
- PRINT("\tSection [%s] links to section [%s], which was "
- "marked for removal--it will not be removed.\n",
- shdr_info[cnt].name,
- shdr_info[shdr_info[cnt].shdr.sh_info].name);
-
- shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1;
- changes |= shdr_info[cnt].shdr.sh_info < cnt;
- }
-
- /* Mark the section as investigated. */
- shdr_info[cnt].idx = 2;
- } /* if (shdr_info[cnt].idx == 1) */
- } /* for (cnt = 1; cnt < shnum; ++cnt) */
- } while (changes);
- }
- else {
- INFO("Not stripping sections.\n");
- /* Mark the SHT_NULL section as handled. */
- shdr_info[0].idx = 2;
- }
-
- /* Mark the section header string table as unused, we will create
- a new one as the very last section in the new ELF file.
- */
- shdr_info[shstrndx].idx = rebuild_shstrtab ? 0 : 2;
-
- /* We need a string table for the section headers. */
- FAILIF_LIBELF((shst = ebl_strtabinit (1 /* null-terminated */)) == NULL,
- ebl_strtabinit);
-
- /* Assign new section numbers. */
- INFO("Creating new sections...\n");
- //shdr_info[0].idx = 0;
- for (cnt = idx = 1; cnt < shnum; ++cnt) {
- if (shdr_info[cnt].idx > 0) {
- shdr_info[cnt].idx = idx++;
-
- /* Create a new section. */
- FAILIF_LIBELF((shdr_info[cnt].newscn =
- elf_newscn(newelf)) == NULL, elf_newscn);
- ASSERT(elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
-
- /* Add this name to the section header string table. */
- shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0);
-
- INFO("\tsection [%s] (old offset %lld, old size %lld) will have index %d "
- "(was %d).\n",
- shdr_info[cnt].name,
- shdr_info[cnt].old_shdr.sh_offset,
- shdr_info[cnt].old_shdr.sh_size,
- shdr_info[cnt].idx,
- elf_ndxscn(shdr_info[cnt].scn));
- } else {
- INFO("\tIgnoring section [%s] (offset %lld, size %lld, index %d), "
- "it will be discarded.\n",
- shdr_info[cnt].name,
- shdr_info[cnt].shdr.sh_offset,
- shdr_info[cnt].shdr.sh_size,
- elf_ndxscn(shdr_info[cnt].scn));
- }
- } /* for */
-
- sections_dropped_or_rearranged = idx != cnt;
-
- Elf_Data *shstrtab_data = NULL;
-
-#if 0
- /* Fail if sections are being dropped or rearranged (except for moving shstrtab) or the
- symbol filter is not empty, AND the file is an executable.
- */
- FAILIF(((idx != cnt && !(cnt - idx == 1 && rebuild_shstrtab)) || sym_filter != NULL) &&
- ehdr->e_type != ET_DYN,
- "You may not rearrange sections or strip symbols on an executable file!\n");
-#endif
-
- INFO("\n\nADJUSTING ELF FILE\n\n");
-
- adjust_elf(elf, elf_name,
- newelf, newelf_name,
- ebl,
- ehdr, /* store ELF header of original library */
- sym_filter, num_symbols,
- shdr_info, shdr_info_len,
- phdr_info,
- idx, /* highest_scn_num */
- shnum,
- shstrndx,
- shst,
- sections_dropped_or_rearranged,
- dynamic_idx, /* index in shdr_info[] of .dynamic section */
- dynsym_idx, /* index in shdr_info[] of dynamic symbol table */
- shady,
- &shstrtab_data,
- ehdr->e_type == ET_DYN, /* adjust section ofsets only when the file is a shared library */
- rebuild_shstrtab);
-
- /* We have everything from the old file. */
- FAILIF_LIBELF(elf_cntl(elf, ELF_C_FDDONE) != 0, elf_cntl);
-
- /* The ELF library better follows our layout when this is not a
- relocatable object file. */
- elf_flagelf (newelf,
- ELF_C_SET,
- (ehdr->e_type != ET_REL ? ELF_F_LAYOUT : 0));
-
- /* Finally write the file. */
- FAILIF_LIBELF(!dry_run && elf_update(newelf, ELF_C_WRITE) == -1, elf_update);
-
- if (shdr_info != NULL) {
- /* For some sections we might have created an table to map symbol
- table indices. */
- for (cnt = 1; cnt < shdr_info_len; ++cnt) {
- FREEIF(shdr_info[cnt].newsymidx);
- FREEIF(shdr_info[cnt].symse);
- if(shdr_info[cnt].dynsymst != NULL)
- ebl_strtabfree (shdr_info[cnt].dynsymst);
- }
- /* Free the memory. */
- FREE (shdr_info);
- }
- FREEIF(phdr_info);
-
- ebl_closebackend(ebl);
-
- /* Free other resources. */
- if (shst != NULL) ebl_strtabfree (shst);
- if (shstrtab_data != NULL)
- FREEIF(shstrtab_data->d_buf);
-}
diff --git a/tools/soslim/soslim.h b/tools/soslim/soslim.h
deleted file mode 100644
index dfcb085..0000000
--- a/tools/soslim/soslim.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef ELFCOPY_H
-#define ELFCOPY_H
-
-#include <libelf.h>
-#include <libebl.h>
-#include <elf.h>
-#include <gelf.h>
-
-/*
-symbol_filter:
- On input: symbol_filter[i] indicates whether to keep a symbol (1) or to
- remove it from the symbol table.
- On output: symbol_filter[i] indicates whether a symbol was removed (0) or
- kept (1) in the symbol table.
-*/
-
-void clone_elf(Elf *elf, Elf *newelf,
- const char *elf_name,
- const char *newelf_name,
- bool *symbol_filter,
- int num_symbols,
- int shady
-#ifdef SUPPORT_ANDROID_PRELINK_TAGS
- , int *prelinked,
- int *elf_little,
- long *prelink_addr
-#endif
- , bool rebuild_shstrtab,
- bool strip_debug,
- bool dry_run);
-
-#endif/*ELFCOPY_H*/
diff --git a/tools/soslim/symfilter.c b/tools/soslim/symfilter.c
deleted file mode 100644
index c21ab2e..0000000
--- a/tools/soslim/symfilter.c
+++ /dev/null
@@ -1,242 +0,0 @@
-#include <debug.h>
-#include <common.h>
-#include <symfilter.h>
-#include <hash.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <libelf.h>
-#include <gelf.h>
-#include <ctype.h>
-
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-static int match_hash_table_section(Elf *elf, Elf_Scn *sect, void *data);
-static int match_dynsym_section(Elf *elf, Elf_Scn *sect, void *data);
-
-void build_symfilter(const char *name, Elf *elf, symfilter_t *filter,
- off_t fsize)
-{
- char *line = NULL;
- symfilter_list_t *symbol;
-
- FAILIF(NULL == name,
- "You must provide a list of symbols to filter on!\n");
-
- filter->num_symbols = 0;
- filter->total_name_length = 0;
-
- /* Open the file. */
- INFO("Opening symbol-filter file %s...\n", name);
- filter->fd = open(name, O_RDONLY);
- FAILIF(filter->fd < 0, "open(%s): %s (%d)\n",
- name,
- strerror(errno),
- errno);
-
- INFO("Symbol-filter file %s is %ld bytes long...\n",
- name,
- fsize);
- filter->fsize = fsize;
-
- /* mmap the symbols file */
- filter->mmap = mmap(NULL, fsize,
- PROT_READ | PROT_WRITE, MAP_PRIVATE,
- filter->fd, 0);
- FAILIF(MAP_FAILED == filter->mmap,
- "mmap(NULL, %ld, PROT_READ, MAP_PRIVATE, %d, 0): %s (%d)\n",
- fsize,
- filter->fd,
- strerror(errno),
- errno);
- INFO("Memory-mapped symbol-filter file at %p\n", filter->mmap);
-
- /* Make sure that the ELF file has a hash table. We will use the hash
- table to look up symbols quickly. If the library does not have a hash-
- table section, we can still do a linear scan, but the code for that is
- not written, as practically every shared library has a hash table.
- */
-
- filter->symtab.sect = NULL;
- map_over_sections(elf, match_dynsym_section, filter);
- FAILIF(NULL == filter->symtab.sect,
- "There is no dynamic-symbol table in this library.\n");
- filter->hash.sect = NULL;
- map_over_sections(elf, match_hash_table_section, filter);
- FAILIF(NULL == filter->hash.sect,
- "There is no hash table in this library.\n");
- INFO("Hash table size 0x%lx, data size 0x%lx.\n",
- (unsigned long)filter->hash.hdr->sh_size,
- (unsigned long)filter->hash.data->d_size);
-
- INFO("Hash table file offset: 0x%x\n", filter->hash.hdr->sh_offset);
-
- GElf_Ehdr *ehdr, ehdr_mem;
- ehdr = gelf_getehdr(elf, &ehdr_mem);
- size_t symsize = gelf_fsize (elf, ELF_T_SYM, 1, ehdr->e_version);
- ASSERT(symsize);
- filter->num_symbols_to_keep = filter->symtab.data->d_size / symsize;
- filter->symbols_to_keep = (bool *)CALLOC(filter->num_symbols_to_keep,
- sizeof(bool));
-
- /* Build the symbol-name chain. */
- INFO("Building symbol list...\n");
-
- line = (char *)filter->mmap;
-
- filter->symbols = NULL;
-#define NOT_DONE ((off_t)(line - (char *)filter->mmap) < fsize)
- do {
- char *name = line;
-
- /* Advance to the next line. We seek out spaces or new lines. At the
- first space or newline character we find, we place a '\0', and
- continue till we've consumed the line. For new lines, we scan both
- '\r' and '\n'. For spaces, we look for ' ', '\t', and '\f'
- */
-
- while (NOT_DONE && !isspace(*line)) line++;
- if (likely(NOT_DONE)) {
- *line++ = '\0';
- if (line - name > 1) {
- /* Add the entry to the symbol-filter list */
- symbol = (symfilter_list_t *)MALLOC(sizeof(symfilter_list_t));
- symbol->next = filter->symbols;
- symbol->name = name;
- filter->symbols = symbol;
-
-#if 0
- /* SLOW! For debugging only! */
- {
- size_t idx;
- size_t elsize = gelf_fsize(elf, ELF_T_SYM, 1,
- ehdr->e_version);
- symbol->index = SHN_UNDEF;
- for (idx = 0; idx < filter->symtab.data->d_size / elsize;
- idx++) {
- GElf_Sym sym_mem;
- GElf_Sym *sym;
- const char *symname;
- sym = gelf_getsymshndx (filter->symtab.data, NULL,
- idx, &sym_mem, NULL);
- ASSERT(sym);
-
- symname = elf_strptr(elf,
- filter->symtab.hdr->sh_link,
- sym->st_name);
- if(!strcmp(symname, symbol->name)) {
- symbol->index = idx;
- break;
- }
- }
- }
-#else
- /* Look up the symbol in the ELF file and associate it with the
- entry in the filter. */
- symbol->index = hash_lookup(elf,
- &filter->hash,
- &filter->symtab,
- symbol->name,
- &symbol->symbol);
-#endif
- symbol->len = line - name - 1;
- ASSERT(symbol->len == strlen(symbol->name));
-
- /* If we didn't find the symbol, then it's not in the library.
- */
-
- if(STN_UNDEF == symbol->index) {
- PRINT("%s: symbol was not found!\n", symbol->name);
- }
- else {
- /* If we found the symbol but it's an undefined symbol, then
- it's not in the library as well. */
- GElf_Sym sym_mem;
- GElf_Sym *sym;
- sym = gelf_getsymshndx (filter->symtab.data, NULL,
- symbol->index, &sym_mem, NULL);
- FAILIF_LIBELF(NULL == sym, gelf_getsymshndx);
- /* Make sure the hash lookup worked. */
- ASSERT(!strcmp(elf_strptr(elf,
- filter->symtab.hdr->sh_link,
- sym->st_name),
- symbol->name));
- if (sym->st_shndx == SHN_UNDEF) {
- PRINT("%s: symbol was not found (undefined)!\n", symbol->name);
- }
- else {
- filter->num_symbols++;
- /* Total count includes null terminators */
- filter->total_name_length += symbol->len + 1;
-
- /* Set the flag in the symbols_to_keep[] array. This indicates
- to function copy_elf() that we want to keep the symbol.
- */
- filter->symbols_to_keep[symbol->index] = true;
- INFO("FILTER-SYMBOL: [%s] [%d bytes]\n",
- symbol->name,
- symbol->len);
- }
- }
- }
- }
- } while (NOT_DONE);
-#undef NOT_DONE
-}
-
-void destroy_symfilter(symfilter_t *filter)
-{
- symfilter_list_t *old;
- INFO("Destroying symbol list...\n");
- while ((old = filter->symbols)) {
- filter->symbols = old->next;
- FREE(old);
- }
- munmap(filter->mmap, filter->fsize);
- close(filter->fd);
-}
-
-static int match_hash_table_section(Elf *elf, Elf_Scn *sect, void *data)
-{
- symfilter_t *filter = (symfilter_t *)data;
- Elf32_Shdr *shdr;
-
- ASSERT(filter);
- ASSERT(sect);
- shdr = elf32_getshdr(sect);
-
- /* The section must be marked both as a SHT_HASH, and it's sh_link field
- must contain the index of our symbol table (per ELF-file spec).
- */
- if (shdr->sh_type == SHT_HASH)
- {
- FAILIF(filter->hash.sect != NULL,
- "There is more than one hash table!\n");
- get_section_info(sect, &filter->hash);
- }
-
- return 0; /* keep looking */
-}
-
-static int match_dynsym_section(Elf *elf, Elf_Scn *sect, void *data)
-{
- symfilter_t *filter = (symfilter_t *)data;
- Elf32_Shdr *shdr;
-
- ASSERT(filter);
- ASSERT(sect);
- shdr = elf32_getshdr(sect);
-
- if (shdr->sh_type == SHT_DYNSYM)
- {
- FAILIF(filter->symtab.sect != NULL,
- "There is more than one dynamic symbol table!\n");
- get_section_info(sect, &filter->symtab);
- }
-
- return 0; /* keep looking */
-}
diff --git a/tools/soslim/symfilter.h b/tools/soslim/symfilter.h
deleted file mode 100644
index f73fd50..0000000
--- a/tools/soslim/symfilter.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef SYMFILTER_H
-#define SYMFILTER_H
-
-/* This file describes the interface for parsing the list of symbols. Currently,
- this is just a text file with each symbol on a separate line. We build an
- in-memory linked list of symbols out of this image.
-*/
-
-#include <stdio.h>
-#include <libelf.h>
-#include <gelf.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <libebl.h> /* defines bool */
-
-typedef struct symfilter_list_t symfilter_list_t;
-struct symfilter_list_t {
- symfilter_list_t *next;
- const char *name;
- unsigned int len; /* strlen(name) */
- Elf32_Word index;
- GElf_Sym symbol;
-};
-
-typedef struct symfilter_t {
-
- int fd; /* symbol-filter-file descriptor */
- off_t fsize; /* size of file */
- void *mmap; /* symbol-fiter-file memory mapping */
-
- section_info_t symtab;
- section_info_t hash;
- symfilter_list_t *symbols;
-
- /* The total number of symbols in the symfilter. */
- unsigned int num_symbols;
- /* The total number of bytes occupied by the names of the symbols, including
- the terminating null characters.
- */
- unsigned int total_name_length;
-
- bool *symbols_to_keep;
- /* must be the same as the number of symbols in the dynamic table! */
- int num_symbols_to_keep;
-} symfilter_t;
-
-void build_symfilter(const char *name, Elf *elf, symfilter_t *filter, off_t);
-void destroy_symfilter(symfilter_t *);
-
-#endif/*SYMFILTER_H*/