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 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 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