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:
commit
802eae98d2
2 changed files with 8 additions and 103 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue