mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 20:05:54 +00:00
Add mmap and nunmap to libc_noux, libc_fs
In the current form, only PROT_READ is supported. This case is emulated by copying the file content into new allocated backing store. Even though the performance benefits of mmap-using code will not be preserved, code that relies on mmap can be executed via the libc_noux or libc_fs plugins, i.e. lightttpd.
This commit is contained in:
parent
d7300e882b
commit
7a7adfbb63
@ -1,5 +1,6 @@
|
||||
SRC_CC = plugin.cc
|
||||
LIBS += libc
|
||||
SRC_CC = plugin.cc
|
||||
LIBS += libc
|
||||
INC_DIR += $(REP_DIR)/src/lib/libc
|
||||
|
||||
vpath plugin.cc $(REP_DIR)/src/lib/libc_fs
|
||||
|
||||
|
@ -23,11 +23,15 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
/* libc plugin interface */
|
||||
#include <libc-plugin/plugin.h>
|
||||
#include <libc-plugin/fd_alloc.h>
|
||||
|
||||
/* libc-internal includes */
|
||||
#include <libc_mem_alloc.h>
|
||||
|
||||
static bool const verbose = false;
|
||||
|
||||
@ -288,6 +292,8 @@ class Plugin : public Libc::Plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
bool supports_mmap() { return true; }
|
||||
|
||||
int chdir(const char *path)
|
||||
{
|
||||
if (*path != '/') {
|
||||
@ -703,6 +709,43 @@ class Plugin : public Libc::Plugin
|
||||
PDBG("write returns %zd", count);
|
||||
return count;
|
||||
}
|
||||
|
||||
void *mmap(void *addr_in, ::size_t length, int prot, int flags,
|
||||
Libc::File_descriptor *fd, ::off_t offset)
|
||||
{
|
||||
if (prot != PROT_READ) {
|
||||
PERR("mmap for prot=%x not supported", prot);
|
||||
errno = EACCES;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
if (addr_in != 0) {
|
||||
PERR("mmap for predefined address not supported");
|
||||
errno = EINVAL;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
void *addr = Libc::mem_alloc()->alloc(length, PAGE_SHIFT);
|
||||
if (addr == (void *)-1) {
|
||||
errno = ENOMEM;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
if (::pread(fd->libc_fd, addr, length, offset) < 0) {
|
||||
PERR("mmap could not obtain file content");
|
||||
::munmap(addr, length);
|
||||
errno = EACCES;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
int munmap(void *addr, ::size_t)
|
||||
{
|
||||
Libc::mem_alloc()->free(addr);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -2,6 +2,8 @@ SRC_CC = plugin.cc
|
||||
|
||||
LIBS += libc
|
||||
|
||||
REP_INC_DIR += src/lib/libc
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/lib/libc_noux
|
||||
|
||||
SHARED_LIB = yes
|
||||
|
@ -34,9 +34,12 @@
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
|
||||
/* libc-internal includes */
|
||||
#include <libc_mem_alloc.h>
|
||||
|
||||
enum { verbose = false };
|
||||
|
||||
@ -543,7 +546,8 @@ namespace {
|
||||
bool supports_socket(int, int, int) { return true; }
|
||||
bool supports_freeaddrinfo(struct addrinfo *) { return true; }
|
||||
bool supports_getaddrinfo(const char *, const char *,
|
||||
struct addrinfo **) { return true; }
|
||||
struct addrinfo **) { return true; }
|
||||
bool supports_mmap() { return true; }
|
||||
|
||||
Libc::File_descriptor *open(char const *, int);
|
||||
ssize_t write(Libc::File_descriptor *, const void *, ::size_t);
|
||||
@ -564,6 +568,9 @@ namespace {
|
||||
int unlink(char const *path);
|
||||
int rename(const char *oldpath, const char *newpath);
|
||||
int mkdir(const char *path, mode_t mode);
|
||||
void *mmap(void *addr, ::size_t length, int prot, int flags,
|
||||
Libc::File_descriptor *, ::off_t offset);
|
||||
int munmap(void *addr, ::size_t length);
|
||||
|
||||
/* Network related functions */
|
||||
Libc::File_descriptor *socket(int, int, int);
|
||||
@ -1089,6 +1096,42 @@ namespace {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *Plugin::mmap(void *addr_in, ::size_t length, int prot, int flags,
|
||||
Libc::File_descriptor *fd, ::off_t offset)
|
||||
{
|
||||
if (prot != PROT_READ) {
|
||||
PERR("mmap for prot=%x not supported", prot);
|
||||
errno = EACCES;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
if (addr_in != 0) {
|
||||
PERR("mmap for predefined address not supported");
|
||||
errno = EINVAL;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
void *addr = Libc::mem_alloc()->alloc(length, PAGE_SHIFT);
|
||||
if (addr == (void *)-1) {
|
||||
errno = ENOMEM;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
if (::pread(fd->libc_fd, addr, length, offset) < 0) {
|
||||
PERR("mmap could not obtain file content");
|
||||
::munmap(addr, length);
|
||||
errno = EACCES;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
int Plugin::munmap(void *addr, ::size_t)
|
||||
{
|
||||
Libc::mem_alloc()->free(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Libc::File_descriptor *Plugin::socket(int domain, int type, int protocol)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user