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