diff --git a/libports/lib/mk/libc_fs.mk b/libports/lib/mk/libc_fs.mk index 948352ca9..c94ce68bc 100644 --- a/libports/lib/mk/libc_fs.mk +++ b/libports/lib/mk/libc_fs.mk @@ -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 diff --git a/libports/src/lib/libc_fs/plugin.cc b/libports/src/lib/libc_fs/plugin.cc index bae5e6492..05b558977 100644 --- a/libports/src/lib/libc_fs/plugin.cc +++ b/libports/src/lib/libc_fs/plugin.cc @@ -23,11 +23,15 @@ #include #include #include +#include +#include /* libc plugin interface */ #include #include +/* libc-internal includes */ +#include 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; + } }; diff --git a/ports/lib/mk/libc_noux.mk b/ports/lib/mk/libc_noux.mk index daac29fed..9b1806b8f 100644 --- a/ports/lib/mk/libc_noux.mk +++ b/ports/lib/mk/libc_noux.mk @@ -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 diff --git a/ports/src/lib/libc_noux/plugin.cc b/ports/src/lib/libc_noux/plugin.cc index a6884e108..5e6d333ca 100644 --- a/ports/src/lib/libc_noux/plugin.cc +++ b/ports/src/lib/libc_noux/plugin.cc @@ -34,9 +34,12 @@ #include #include #include +#include #include #include +/* libc-internal includes */ +#include 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) {