• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2011, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "librsloader.h"
18 #include "utils/rsl_assert.h"
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <time.h>
24 
25 #include <fcntl.h>
26 #include <sys/mman.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30 
31 struct func_entry_t {
32   char const *name;
33   size_t name_len;
34   void *addr;
35 };
36 
find_sym(void * context,char const * name)37 void *find_sym(void *context, char const *name) {
38   static struct func_entry_t const tab[] = {
39 #define DEF(NAME, ADDR) \
40     { NAME, sizeof(NAME) - 1, (void *)(&(ADDR)) },
41 
42     DEF("printf", printf)
43     DEF("scanf", scanf)
44     DEF("__isoc99_scanf", scanf)
45     DEF("rand", rand)
46     DEF("time", time)
47     DEF("srand", srand)
48 #undef DEF
49   };
50 
51   static size_t const tab_size = sizeof(tab) / sizeof(struct func_entry_t);
52 
53   // Note: Since our table is small, we are using trivial O(n) searching
54   // function.  For bigger table, it will be better to use binary
55   // search or hash function.
56   size_t i;
57   size_t name_len = strlen(name);
58   for (i = 0; i < tab_size; ++i) {
59     if (name_len == tab[i].name_len && strcmp(name, tab[i].name) == 0) {
60       return tab[i].addr;
61     }
62   }
63 
64   rsl_assert(0 && "Can't find symbol.");
65   return 0;
66 }
67 
main(int argc,char ** argv)68 int main(int argc, char **argv) {
69   if (argc < 2) {
70     fprintf(stderr, "USAGE: %s [ELF] [ARGS]\n", argv[0]);
71     exit(EXIT_FAILURE);
72   }
73 
74   int fd = open(argv[1], O_RDONLY);
75   if (fd < 0) {
76     fprintf(stderr, "ERROR: Unable to open the file: %s\n", argv[1]);
77     exit(EXIT_FAILURE);
78   }
79 
80   struct stat sb;
81   if (fstat(fd, &sb) != 0) {
82     fprintf(stderr, "ERROR: Unable to stat the file: %s\n", argv[1]);
83     close(fd);
84     exit(EXIT_FAILURE);
85   }
86 
87   unsigned char const *image = (unsigned char const *)
88     mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
89 
90   if (image == MAP_FAILED) {
91     fprintf(stderr, "ERROR: Unable to mmap the file: %s\n", argv[1]);
92     close(fd);
93     exit(EXIT_FAILURE);
94   }
95 
96   RSExecRef object = rsloaderCreateExec(image, sb.st_size, find_sym, 0);
97   if (!object) {
98     fprintf(stderr, "ERROR: Unable to load elf object.\n");
99     close(fd);
100     exit(EXIT_FAILURE);
101   }
102 
103   int (*main_stub)(int, char **) =
104     (int (*)(int, char **))rsloaderGetSymbolAddress(object, "main");
105 
106   int ret = main_stub(argc - 1, argv + 1);
107   printf("============================================================\n");
108   printf("ELF object finished with code: %d\n", ret);
109   fflush(stdout);
110 
111   rsloaderDisposeExec(object);
112 
113   close(fd);
114 
115   return EXIT_SUCCESS;
116 }
117