test-librsloader.c revision a4e5f360d91ca11fc12b322d1a2bb25609b214d1
1a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao/* 2a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * Copyright 2011, The Android Open Source Project 3a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * 4a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License"); 5a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * you may not use this file except in compliance with the License. 6a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * You may obtain a copy of the License at 7a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * 8a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * http://www.apache.org/licenses/LICENSE-2.0 9a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * 10a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * Unless required by applicable law or agreed to in writing, software 11a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS, 12a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * See the License for the specific language governing permissions and 14a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * limitations under the License. 15a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao */ 16a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao 1758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include "librsloader.h" 18c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa#include "utils/rsl_assert.h" 1958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 2058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include <stdio.h> 2158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include <stdlib.h> 2258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include <string.h> 2358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include <time.h> 2458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 2558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include <fcntl.h> 2658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include <sys/mman.h> 2758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include <sys/stat.h> 2858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include <sys/types.h> 2958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include <unistd.h> 3058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 3158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chienstruct func_entry_t { 3258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien char const *name; 3358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien size_t name_len; 3458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien void *addr; 3558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien}; 3658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 3758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chienvoid *find_sym(void *context, char const *name) { 3858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien static struct func_entry_t const tab[] = { 3958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#define DEF(NAME, ADDR) \ 4058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien { NAME, sizeof(NAME) - 1, (void *)(&(ADDR)) }, 4158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 4258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien DEF("printf", printf) 4358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien DEF("scanf", scanf) 4458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien DEF("__isoc99_scanf", scanf) 4558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien DEF("rand", rand) 4658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien DEF("time", time) 4758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien DEF("srand", srand) 4858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#undef DEF 4958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien }; 5058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 5158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien static size_t const tab_size = sizeof(tab) / sizeof(struct func_entry_t); 5258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 5358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien // Note: Since our table is small, we are using trivial O(n) searching 5458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien // function. For bigger table, it will be better to use binary 5558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien // search or hash function. 5658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien size_t i; 5758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien size_t name_len = strlen(name); 5858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien for (i = 0; i < tab_size; ++i) { 5958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien if (name_len == tab[i].name_len && strcmp(name, tab[i].name) == 0) { 6058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien return tab[i].addr; 6158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien } 6258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien } 6358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 64c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa rsl_assert(0 && "Can't find symbol."); 6558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien return 0; 6658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien} 6758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 6858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chienint main(int argc, char **argv) { 6958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien if (argc < 2) { 7058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien fprintf(stderr, "USAGE: %s [ELF] [ARGS]\n", argv[0]); 7158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien exit(EXIT_FAILURE); 7258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien } 7358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 7458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien int fd = open(argv[1], O_RDONLY); 7558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien if (fd < 0) { 7658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien fprintf(stderr, "ERROR: Unable to open the file: %s\n", argv[1]); 7758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien exit(EXIT_FAILURE); 7858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien } 7958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 8058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien struct stat sb; 8158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien if (fstat(fd, &sb) != 0) { 8258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien fprintf(stderr, "ERROR: Unable to stat the file: %s\n", argv[1]); 8358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien close(fd); 8458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien exit(EXIT_FAILURE); 8558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien } 8658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 8758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien unsigned char const *image = (unsigned char const *) 8858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 8958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 9058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien if (image == MAP_FAILED) { 9158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien fprintf(stderr, "ERROR: Unable to mmap the file: %s\n", argv[1]); 9258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien close(fd); 9358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien exit(EXIT_FAILURE); 9458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien } 9558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 9658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien RSExecRef object = rsloaderCreateExec(image, sb.st_size, find_sym, 0); 9758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien if (!object) { 9858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien fprintf(stderr, "ERROR: Unable to load elf object.\n"); 9958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien close(fd); 10058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien exit(EXIT_FAILURE); 10158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien } 10258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 10358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien int (*main_stub)(int, char **) = 10458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien (int (*)(int, char **))rsloaderGetSymbolAddress(object, "main"); 10558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 10658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien int ret = main_stub(argc - 1, argv + 1); 10758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien printf("============================================================\n"); 10858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien printf("ELF object finished with code: %d\n", ret); 10958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien fflush(stdout); 11058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 11158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien rsloaderDisposeExec(object); 11258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 11358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien close(fd); 11458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 11558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien return EXIT_SUCCESS; 11658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien} 117