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