mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-12 13:48:30 +00:00
libc: Add munmap support to plugin interface
With this patch, libc plugins become able to handle munmap for regions attached by the plugin.
This commit is contained in:
parent
3546b17827
commit
4914032800
@ -58,6 +58,7 @@ namespace Libc {
|
||||
virtual bool supports_socket(int domain, int type, int protocol);
|
||||
virtual bool supports_stat(const char *path);
|
||||
virtual bool supports_unlink(const char *path);
|
||||
virtual bool supports_mmap();
|
||||
|
||||
virtual File_descriptor *accept(File_descriptor *,
|
||||
struct ::sockaddr *addr,
|
||||
@ -98,6 +99,7 @@ namespace Libc {
|
||||
virtual int mkdir(const char *pathname, mode_t mode);
|
||||
virtual void *mmap(void *addr, ::size_t length, int prot, int flags,
|
||||
File_descriptor *, ::off_t offset);
|
||||
virtual int munmap(void *addr, ::size_t length);
|
||||
virtual File_descriptor *open(const char *pathname, int flags);
|
||||
virtual int pipe(File_descriptor *pipefd[2]);
|
||||
virtual ssize_t read(File_descriptor *, void *buf, ::size_t count);
|
||||
|
@ -10,7 +10,7 @@ LIBS += timed_semaphore cxx
|
||||
#
|
||||
# Back end
|
||||
#
|
||||
SRC_CC = atexit.cc dummies.cc rlimit.cc sysctl.cc readlink.cc munmap.cc \
|
||||
SRC_CC = atexit.cc dummies.cc rlimit.cc sysctl.cc readlink.cc \
|
||||
issetugid.cc errno.cc gai_strerror.cc clock_gettime.cc \
|
||||
gettimeofday.cc malloc.cc progname.cc fd_alloc.cc file_operations.cc \
|
||||
plugin.cc plugin_registry.cc select.cc exit.cc environ.cc nanosleep.cc \
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
/* libc-internal includes */
|
||||
#include "libc_mem_alloc.h"
|
||||
#include "libc_mmap_registry.h"
|
||||
|
||||
using namespace Libc;
|
||||
|
||||
@ -43,6 +44,13 @@ using namespace Libc;
|
||||
enum { INVALID_FD = -1 };
|
||||
|
||||
|
||||
Libc::Mmap_registry *Libc::mmap_registry()
|
||||
{
|
||||
static Libc::Mmap_registry registry;
|
||||
return ®istry;
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** Utilities **
|
||||
***************/
|
||||
@ -295,17 +303,48 @@ extern "C" void *mmap(void *addr, ::size_t length, int prot, int flags,
|
||||
int libc_fd, ::off_t offset)
|
||||
{
|
||||
/* handle requests for anonymous memory */
|
||||
if (!addr && libc_fd == -1)
|
||||
return Libc::mem_alloc()->alloc(length, PAGE_SHIFT);
|
||||
if (!addr && libc_fd == -1) {
|
||||
PDBG("call Libc::mem_alloc()->alloc(%zd)", length);
|
||||
void *start = Libc::mem_alloc()->alloc(length, PAGE_SHIFT);
|
||||
mmap_registry()->insert(start, length, 0);
|
||||
PDBG("return addr %p", start);
|
||||
return start;
|
||||
}
|
||||
|
||||
/* lookup plugin responsible for file descriptor */
|
||||
File_descriptor *fd = libc_fd_to_fd(libc_fd, "mmap");
|
||||
if (!fd || !fd->plugin) {
|
||||
if (!fd || !fd->plugin || !fd->plugin->supports_mmap()) {
|
||||
PWRN("mmap not supported for file descriptor %d", libc_fd);
|
||||
return (void *)INVALID_FD;
|
||||
}
|
||||
|
||||
return fd->plugin->mmap(addr, length, prot, flags, fd, offset);
|
||||
void *start = fd->plugin->mmap(addr, length, prot, flags, fd, offset);
|
||||
mmap_registry()->insert(start, length, fd->plugin);
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int munmap(void *start, size_t length)
|
||||
{
|
||||
if (!mmap_registry()->is_registered(start)) {
|
||||
PWRN("munmap: could not lookup plugin for address %p", start);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup plugin that was used for mmap
|
||||
*
|
||||
* If the pointer is NULL, 'start' refers to an anonymous mmap.
|
||||
*/
|
||||
Plugin *plugin = mmap_registry()->lookup_plugin_by_addr(start);
|
||||
|
||||
if (!plugin) {
|
||||
Libc::mem_alloc()->free(start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return plugin->munmap(start, length);
|
||||
}
|
||||
|
||||
|
||||
|
108
libports/src/lib/libc/libc_mmap_registry.h
Normal file
108
libports/src/lib/libc/libc_mmap_registry.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* \brief Registry for keeping track of mmapped regions
|
||||
* \author Norman Feske
|
||||
* \date 2012-08-16
|
||||
*/
|
||||
|
||||
#ifndef _LIBC_MMAP_REGISTRY_H_
|
||||
#define _LIBC_MMAP_REGISTRY_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/lock.h>
|
||||
#include <base/env.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
/* libc-internal includes */
|
||||
#include <libc-plugin/plugin.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <errno.h>
|
||||
|
||||
namespace Libc {
|
||||
|
||||
class Mmap_registry;
|
||||
|
||||
/**
|
||||
* Return singleton instance of mmap registry
|
||||
*/
|
||||
Mmap_registry *mmap_registry();
|
||||
}
|
||||
|
||||
|
||||
class Libc::Mmap_registry
|
||||
{
|
||||
public:
|
||||
|
||||
struct Entry : Genode::List<Entry>::Element
|
||||
{
|
||||
void * const start;
|
||||
Plugin * const plugin;
|
||||
|
||||
Entry(void *start, Plugin *plugin)
|
||||
: start(start), plugin(plugin) { }
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Genode::List<Mmap_registry::Entry> _list;
|
||||
|
||||
Genode::Lock mutable _lock;
|
||||
|
||||
Entry *_lookup_by_addr_unsynchronized(void * const start) const
|
||||
{
|
||||
Entry *curr = _list.first();
|
||||
|
||||
for (; curr; curr = curr->next())
|
||||
if (curr->start == start)
|
||||
return curr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void insert(void *start, Genode::size_t len, Plugin *plugin)
|
||||
{
|
||||
Genode::Lock::Guard guard(_lock);
|
||||
|
||||
if (_lookup_by_addr_unsynchronized(start)) {
|
||||
PINF("mmap region at %p is already registered", start);
|
||||
return;
|
||||
}
|
||||
|
||||
_list.insert(new (Genode::env()->heap()) Entry(start, plugin));
|
||||
}
|
||||
|
||||
Plugin *lookup_plugin_by_addr(void *start) const
|
||||
{
|
||||
Genode::Lock::Guard guard(_lock);
|
||||
|
||||
Entry * const e = _lookup_by_addr_unsynchronized(start);
|
||||
return e ? e->plugin : 0;
|
||||
}
|
||||
|
||||
bool is_registered(void *start) const
|
||||
{
|
||||
Genode::Lock::Guard guard(_lock);
|
||||
|
||||
return _lookup_by_addr_unsynchronized(start) != 0;
|
||||
}
|
||||
|
||||
void remove(void *start)
|
||||
{
|
||||
Genode::Lock::Guard guard(_lock);
|
||||
|
||||
Entry *e = _lookup_by_addr_unsynchronized(start);
|
||||
|
||||
if (!e) {
|
||||
PWRN("lookup for address %p in in mmap registry failed", start);
|
||||
return;
|
||||
}
|
||||
|
||||
_list.remove(e);
|
||||
destroy(Genode::env()->heap(), e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif /* _LIBC_MMAP_REGISTRY_H_ */
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* \brief C-library back end
|
||||
* \author Norman Feske
|
||||
* \date 2008-11-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2008-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "libc_debug.h"
|
||||
|
||||
extern "C" int munmap(void *start, size_t length)
|
||||
{
|
||||
raw_write_str("munmap called, not yet implemented!\n");
|
||||
return 0;
|
||||
}
|
@ -110,6 +110,13 @@ bool Plugin::supports_unlink(const char*)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Plugin::supports_mmap()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default implementations
|
||||
*/
|
||||
@ -181,6 +188,7 @@ DUMMY(int, -1, getaddrinfo, (const char *, const char *, const struct ::addrinf
|
||||
DUMMY(int, -1, mkdir, (const char*, mode_t));
|
||||
DUMMY(void *, (void *)(-1), mmap, (void *addr, ::size_t length, int prot, int flags,
|
||||
File_descriptor *, ::off_t offset));
|
||||
DUMMY(int, -1, munmap, (void *, ::size_t));
|
||||
DUMMY(int, -1, pipe, (File_descriptor*[2]));
|
||||
DUMMY(int, -1, rename, (const char *, const char *));
|
||||
DUMMY(int, -1, select, (int, fd_set *, fd_set *, fd_set *, struct timeval *));
|
||||
|
Loading…
x
Reference in New Issue
Block a user