[Pal/FreeBSD] specify loaded address of exec in child process

This is the FreeBSD version of https://reviewable.io/reviews/oscarlab/graphene/372
I haven't tested this PR.

Signed-off-by: Isaku Yamahata <isaku.yamahata@gmail.com>
This commit is contained in:
Isaku Yamahata
2019-04-23 16:52:04 -07:00
parent c7296d2512
commit 3776e014dd
4 changed files with 36 additions and 0 deletions
+11
View File
@@ -63,6 +63,7 @@ static int file_open (PAL_HANDLE * handle, const char * type, const char * uri,
hdl->file.offset = 0;
hdl->file.append = 0;
hdl->file.pass = 0;
hdl->file.map_start = NULL;
char * path = (void *) hdl + HANDLE_SIZE(file);
memcpy(path, uri, len + 1);
hdl->file.realpath = path;
@@ -154,6 +155,16 @@ static int file_map (PAL_HANDLE handle, void ** addr, int prot,
{
int fd = handle->file.fd;
void * mem = *addr;
/*
* work around for fork emulation
* the first exec image to be loaded has to be at same address
* as parent.
*/
if (mem == NULL && handle->file.map_start != NULL) {
mem = (PAL_PTR)handle->file.map_start;
/* this address is used. don't over-map it later */
handle->file.map_start = NULL;
}
int flags = MAP_FILE|HOST_FLAGS(0, prot)|(mem ? MAP_FIXED : 0);
prot = HOST_PROT(prot);
+4
View File
@@ -242,6 +242,10 @@ void pal_bsd_main (void * args)
SET_HANDLE_TYPE(file, file);
file->hdr.flags |= RFD(0)|WFD(0)|WRITEABLE(0);
file->file.fd = fd;
file->file.offset = 0;
file->file.append = false;
file->file.pass = false;
file->file.map_start = NULL;
char * path = (void *) file + HANDLE_SIZE(file);
get_norm_path(argv[0], path, 0, len + 1);
file->file.realpath = path;
+15
View File
@@ -36,6 +36,7 @@
#include "pal_debug.h"
#include "pal_error.h"
#include "pal_security.h"
#include "pal_rtld.h"
#include "api.h"
#include <sched.h>
@@ -169,6 +170,20 @@ int _DkProcessCreate (PAL_HANDLE * handle, const char * uri, const char ** args)
return ret;
handle_set_cloexec(exec, true);
/* If this process creation is for fork emulation,
* map address of executable is already determined.
* tell its address to forked process.
*/
size_t len;
const char * file_uri = "file:";
if (exec_map && exec_map->l_name &&
(len = strlen(uri)) >= 5 && !memcmp(uri, file_uri, 5) &&
/* skip "file:"*/
strlen(exec_map->l_name) == len - 5 &&
/* + 1 for lasting * NUL */
!memcmp(exec_map->l_name, uri + 5, len - 5 + 1))
exec->file.map_start = (PAL_PTR)exec_map->l_map_start;
}
/* step 2: create parant and child process handle */
+6
View File
@@ -76,6 +76,12 @@ typedef union pal_handle
PAL_BOL append;
PAL_BOL pass;
PAL_STR realpath;
/*
* map_start is to request this file should be mapped to this
* address. When fork is emulated, the address is already
* determined by parent process.
*/
PAL_PTR map_start;
} file;
struct {