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