1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

Merge pull request #20 from stv0g/linux-elf-loader

Simplified proxy by moving ELF parsing to kernel
This commit is contained in:
Stefan Lankes 2016-04-05 14:31:51 +02:00
commit 802eae98d2
2 changed files with 8 additions and 103 deletions

View file

@ -13,7 +13,6 @@ HermitCore is the result of a research project at RWTH Aachen University and is
* Netwide Assembler (NASM)
* GNU Make, GNU Binutils
* Tools and libraries to build *linux*, *binutils* and *gcc* (e.g. flex, bison, MPFR library, GMP library, MPC library, ISL library)
* libelf
* texinfo
* Qemu

View file

@ -33,10 +33,8 @@
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <gelf.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sendfile.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/tcp.h>
@ -58,7 +56,6 @@
static int sobufsize = 131072;
static unsigned int isle_nr = 0;
static char fname[] = "/tmp/hermitXXXXXX";
extern char **environ;
@ -69,7 +66,6 @@ static void fini_env(void)
{
dump_log();
stop_hermit();
unlink(fname);
}
static void exit_handler(int sig)
@ -77,100 +73,6 @@ static void exit_handler(int sig)
exit(0);
}
static int load_elf(int dest_fd, int elf_fd)
{
Elf *elf;
GElf_Ehdr ehdr;
GElf_Phdr phdr ;
size_t n;
int ret;
int i;
if (elf_version(EV_CURRENT) == EV_NONE)
return -1;
elf = elf_begin(elf_fd, ELF_C_READ, NULL);
if (!elf)
return -1;
if (elf_kind(elf) != ELF_K_ELF)
goto out;
if (gelf_getehdr(elf, &ehdr) != &ehdr)
goto out;
if (ehdr.e_ident[EI_OSABI] != HERMIT_ELFOSABI)
goto out;
if (elf_getphdrnum(elf , &n) != 0)
goto out;
for (i = 0; i < n ; i ++) {
ssize_t ret;
off_t offset;
if (gelf_getphdr(elf, i, &phdr) != & phdr )
continue;
if (phdr.p_type != PT_LOAD)
continue;
offset = phdr.p_offset;
ret = sendfile(dest_fd, elf_fd, &offset, phdr.p_filesz);
if (ret != phdr.p_filesz || offset != phdr.p_offset + phdr.p_filesz)
goto out;
}
ret = 0;
out: elf_end(elf);
return ret;
}
static int load_bin(const char *app)
{
int tmp_fd, elf_fd, ret;
FILE *file;
mkstemp(fname);
// register function to delete temporary files
atexit(fini_env);
tmp_fd = open(fname, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
if (tmp_fd < 0) {
perror("open");
exit(1);
}
// get text section from elf binary
elf_fd = open(app, O_RDONLY, 0);
if (elf_fd < 0) {
perror("open");
exit(1);
}
ret = load_elf(tmp_fd, elf_fd);
if (ret)
goto out;
// set path to temporary file
file = fopen("/sys/hermit/path", "w");
if (!file) {
perror("fopen");
exit(1);
}
fprintf(file, "%s", fname);
fclose(file);
out: close(tmp_fd);
close(elf_fd);
return ret;
}
static int init_env(const char *path)
{
int ret;
@ -206,13 +108,16 @@ static int init_env(const char *path)
isle_nr = 0;
}
// load application
ret = load_bin(path);
if (ret) {
perror("Failed to load binary");
// set path to temporary file
file = fopen("/sys/hermit/path", "w");
if (!file) {
perror("fopen");
exit(1);
}
fprintf(file, "%s", path);
fclose(file);
// start application
snprintf(isle_path, MAX_PATH, "/sys/hermit/isle%d/cpus", isle_nr);
file = fopen(isle_path, "w");
@ -505,6 +410,7 @@ int main(int argc, char **argv)
struct sockaddr_in serv_name;
init_env(argv[1]);
atexit(fini_env);
/* create a socket */
s = socket(PF_INET, SOCK_STREAM, 0);