blob: 3c9ac2ded82bb044beef3a7e8e5c2b7c5e94be72 [file] [log] [blame]
/*
* Copyright 2011, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "librsloader.h"
#include "utils/rsl_assert.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
struct func_entry_t {
char const *name;
size_t name_len;
void *addr;
};
void *find_sym(void *context, char const *name) {
static struct func_entry_t const tab[] = {
#define DEF(NAME, ADDR) \
{ NAME, sizeof(NAME) - 1, (void *)(&(ADDR)) },
DEF("printf", printf)
DEF("scanf", scanf)
DEF("__isoc99_scanf", scanf)
DEF("rand", rand)
DEF("time", time)
DEF("srand", srand)
#undef DEF
};
static size_t const tab_size = sizeof(tab) / sizeof(struct func_entry_t);
// Note: Since our table is small, we are using trivial O(n) searching
// function. For bigger table, it will be better to use binary
// search or hash function.
size_t i;
size_t name_len = strlen(name);
for (i = 0; i < tab_size; ++i) {
if (name_len == tab[i].name_len && strcmp(name, tab[i].name) == 0) {
return tab[i].addr;
}
}
rsl_assert(0 && "Can't find symbol.");
return 0;
}
int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "USAGE: %s [ELF] [ARGS]\n", argv[0]);
exit(EXIT_FAILURE);
}
int fd = open(argv[1], O_RDONLY);
if (fd < 0) {
fprintf(stderr, "ERROR: Unable to open the file: %s\n", argv[1]);
exit(EXIT_FAILURE);
}
struct stat sb;
if (fstat(fd, &sb) != 0) {
fprintf(stderr, "ERROR: Unable to stat the file: %s\n", argv[1]);
close(fd);
exit(EXIT_FAILURE);
}
unsigned char const *image = (unsigned char const *)
mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (image == MAP_FAILED) {
fprintf(stderr, "ERROR: Unable to mmap the file: %s\n", argv[1]);
close(fd);
exit(EXIT_FAILURE);
}
RSExecRef object = rsloaderCreateExec(image, sb.st_size, find_sym, 0);
if (!object) {
fprintf(stderr, "ERROR: Unable to load elf object.\n");
close(fd);
exit(EXIT_FAILURE);
}
int (*main_stub)(int, char **) =
(int (*)(int, char **))rsloaderGetSymbolAddress(object, "main");
int ret = main_stub(argc - 1, argv + 1);
printf("============================================================\n");
printf("ELF object finished with code: %d\n", ret);
fflush(stdout);
rsloaderDisposeExec(object);
close(fd);
return EXIT_SUCCESS;
}