test-librsloader.c revision c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9
1#include "librsloader.h"
2#include "utils/rsl_assert.h"
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <time.h>
8
9#include <fcntl.h>
10#include <sys/mman.h>
11#include <sys/stat.h>
12#include <sys/types.h>
13#include <unistd.h>
14
15struct func_entry_t {
16  char const *name;
17  size_t name_len;
18  void *addr;
19};
20
21void *find_sym(void *context, char const *name) {
22  static struct func_entry_t const tab[] = {
23#define DEF(NAME, ADDR) \
24    { NAME, sizeof(NAME) - 1, (void *)(&(ADDR)) },
25
26    DEF("printf", printf)
27    DEF("scanf", scanf)
28    DEF("__isoc99_scanf", scanf)
29    DEF("rand", rand)
30    DEF("time", time)
31    DEF("srand", srand)
32#undef DEF
33  };
34
35  static size_t const tab_size = sizeof(tab) / sizeof(struct func_entry_t);
36
37  // Note: Since our table is small, we are using trivial O(n) searching
38  // function.  For bigger table, it will be better to use binary
39  // search or hash function.
40  size_t i;
41  size_t name_len = strlen(name);
42  for (i = 0; i < tab_size; ++i) {
43    if (name_len == tab[i].name_len && strcmp(name, tab[i].name) == 0) {
44      return tab[i].addr;
45    }
46  }
47
48  rsl_assert(0 && "Can't find symbol.");
49  return 0;
50}
51
52int main(int argc, char **argv) {
53  if (argc < 2) {
54    fprintf(stderr, "USAGE: %s [ELF] [ARGS]\n", argv[0]);
55    exit(EXIT_FAILURE);
56  }
57
58  int fd = open(argv[1], O_RDONLY);
59  if (fd < 0) {
60    fprintf(stderr, "ERROR: Unable to open the file: %s\n", argv[1]);
61    exit(EXIT_FAILURE);
62  }
63
64  struct stat sb;
65  if (fstat(fd, &sb) != 0) {
66    fprintf(stderr, "ERROR: Unable to stat the file: %s\n", argv[1]);
67    close(fd);
68    exit(EXIT_FAILURE);
69  }
70
71  unsigned char const *image = (unsigned char const *)
72    mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
73
74  if (image == MAP_FAILED) {
75    fprintf(stderr, "ERROR: Unable to mmap the file: %s\n", argv[1]);
76    close(fd);
77    exit(EXIT_FAILURE);
78  }
79
80  RSExecRef object = rsloaderCreateExec(image, sb.st_size, find_sym, 0);
81  if (!object) {
82    fprintf(stderr, "ERROR: Unable to load elf object.\n");
83    close(fd);
84    exit(EXIT_FAILURE);
85  }
86
87  int (*main_stub)(int, char **) =
88    (int (*)(int, char **))rsloaderGetSymbolAddress(object, "main");
89
90  int ret = main_stub(argc - 1, argv + 1);
91  printf("============================================================\n");
92  printf("ELF object finished with code: %d\n", ret);
93  fflush(stdout);
94
95  rsloaderDisposeExec(object);
96
97  close(fd);
98
99  return EXIT_SUCCESS;
100}
101