summaryrefslogtreecommitdiffstats
path: root/tools/isprelinked/isprelinked.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/isprelinked/isprelinked.c')
-rw-r--r--tools/isprelinked/isprelinked.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/tools/isprelinked/isprelinked.c b/tools/isprelinked/isprelinked.c
new file mode 100644
index 0000000..c677e39
--- /dev/null
+++ b/tools/isprelinked/isprelinked.c
@@ -0,0 +1,89 @@
+/* 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 <libelf.h>
+#include <libebl.h>
+#ifdef ARM_SPECIFIC_HACKS
+ #include <libebl_arm.h>
+#endif/*ARM_SPECIFIC_HACKS*/
+#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>
+#include <rangesort.h>
+#include <prelink_info.h>
+#include <libgen.h>
+
+
+/* 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;
+
+int main(int argc, char **argv) {
+
+ argc--, argv++;
+ if (!argc)
+ return 0;
+
+ /* Check to see whether the ELF library is current. */
+ FAILIF (elf_version(EV_CURRENT) == EV_NONE, "libelf is out of date!\n");
+
+ const char *filename;
+ for (; argc; argc--) {
+ filename = *argv++;
+
+ Elf *elf;
+ GElf_Ehdr elf_hdr;
+ int fd;
+ int prelinked;
+ long prelink_addr = 0;
+
+ INFO("Processing file [%s]\n", filename);
+
+ fd = open(filename, O_RDONLY);
+ FAILIF(fd < 0, "open(%d): %s (%d).\n",
+ filename,
+ strerror(errno),
+ errno);
+
+ elf = elf_begin(fd, ELF_C_READ_MMAP_PRIVATE, NULL);
+ FAILIF_LIBELF(elf == NULL, elf_begin);
+
+ FAILIF_LIBELF(0 == gelf_getehdr(elf, &elf_hdr),
+ gelf_getehdr);
+
+#ifdef SUPPORT_ANDROID_PRELINK_TAGS
+ prelinked = check_prelinked(filename, elf_hdr.e_ident[EI_DATA] == ELFDATA2LSB,
+ &prelink_addr);
+#else
+ #error 'SUPPORT_ANDROID_PRELINK_TAGS is not defined!'
+#endif
+
+ if (prelinked)
+ PRINT("%s: 0x%08x\n", filename, prelink_addr);
+ else
+ PRINT("%s: not prelinked\n", filename);
+
+ FAILIF_LIBELF(elf_end(elf), elf_end);
+ close(fd);
+ }
+
+ return 0;
+}
+