* mmap.cc (list::match): Add parameters to return valid address and
length back to munmap(). Evaluate intersection between given area and mapped area and return it, if any. (mmap64): On regular files, don't allow mappings beginning beyond EOF. Return with errno set to ENXIO instead. (munmap): Rewrite SUSv3 conformant. Check if given memory area is valid. Unmap all maps inside given memory area. Don't return error if no mapping has been unmapped.
This commit is contained in:
parent
4b2cbaeefd
commit
f2d3c47b14
|
@ -1,4 +1,15 @@
|
||||||
2003-07-04 N Stephens <nigel@mips.com>
|
2003-07-05 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* mmap.cc (list::match): Add parameters to return valid address and
|
||||||
|
length back to munmap(). Evaluate intersection between given
|
||||||
|
area and mapped area and return it, if any.
|
||||||
|
(mmap64): On regular files, don't allow mappings beginning beyond
|
||||||
|
EOF. Return with errno set to ENXIO instead.
|
||||||
|
(munmap): Rewrite SUSv3 conformant. Check if given memory area is
|
||||||
|
valid. Unmap all maps inside given memory area. Don't return error
|
||||||
|
if no mapping has been unmapped.
|
||||||
|
|
||||||
|
2003-07-05 N Stephens <nigel@mips.com>
|
||||||
|
|
||||||
* fhandler.h (fhandler_socket::get_connect_state): New method to
|
* fhandler.h (fhandler_socket::get_connect_state): New method to
|
||||||
return socket connection state.
|
return socket connection state.
|
||||||
|
|
|
@ -270,7 +270,8 @@ public:
|
||||||
void erase (int i);
|
void erase (int i);
|
||||||
void erase ();
|
void erase ();
|
||||||
mmap_record *match (_off64_t off, DWORD len);
|
mmap_record *match (_off64_t off, DWORD len);
|
||||||
long match (caddr_t addr, DWORD len, long start);
|
long match (caddr_t addr, DWORD len, caddr_t &m_addr, DWORD &m_len,
|
||||||
|
long start);
|
||||||
};
|
};
|
||||||
|
|
||||||
list::list ()
|
list::list ()
|
||||||
|
@ -323,13 +324,24 @@ list::match (_off64_t off, DWORD len)
|
||||||
|
|
||||||
/* Used in munmap() */
|
/* Used in munmap() */
|
||||||
long
|
long
|
||||||
list::match (caddr_t addr, DWORD len, _off_t start)
|
list::match (caddr_t addr, DWORD len, caddr_t &m_addr, DWORD &m_len,
|
||||||
|
_off_t start)
|
||||||
{
|
{
|
||||||
|
caddr_t low, high;
|
||||||
|
|
||||||
for (int i = start + 1; i < nrecs; ++i)
|
for (int i = start + 1; i < nrecs; ++i)
|
||||||
if (addr >= recs[i].get_address ()
|
{
|
||||||
&& addr + len <= recs[i].get_address ()
|
low = (addr >= recs[i].get_address ()) ? addr : recs[i].get_address ();
|
||||||
+ (PAGE_CNT (recs[i].get_size ()) * getpagesize ()))
|
high = recs[i].get_address ()
|
||||||
return i;
|
+ (PAGE_CNT (recs[i].get_size ()) * getpagesize ());
|
||||||
|
high = (addr + len < high) ? addr + len : high;
|
||||||
|
if (low < high)
|
||||||
|
{
|
||||||
|
m_addr = low;
|
||||||
|
m_len = high - low;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,6 +498,16 @@ mmap64 (caddr_t addr, size_t len, int prot, int flags, int fd, _off64_t off)
|
||||||
DWORD high;
|
DWORD high;
|
||||||
DWORD low = GetFileSize (fh->get_handle (), &high);
|
DWORD low = GetFileSize (fh->get_handle (), &high);
|
||||||
_off64_t fsiz = ((_off64_t)high << 32) + low;
|
_off64_t fsiz = ((_off64_t)high << 32) + low;
|
||||||
|
/* Don't allow mappings beginning beyond EOF since Windows can't
|
||||||
|
handle that POSIX like. FIXME: Still looking for a good idea
|
||||||
|
to allow that nevertheless. */
|
||||||
|
if (gran_off >= fsiz)
|
||||||
|
{
|
||||||
|
set_errno (ENXIO);
|
||||||
|
ReleaseResourceLock (LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK,
|
||||||
|
"mmap");
|
||||||
|
return MAP_FAILED;
|
||||||
|
}
|
||||||
fsiz -= gran_off;
|
fsiz -= gran_off;
|
||||||
if (gran_len > fsiz)
|
if (gran_len > fsiz)
|
||||||
gran_len = fsiz;
|
gran_len = fsiz;
|
||||||
|
@ -591,16 +613,16 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, _off_t off)
|
||||||
return mmap64 (addr, len, prot, flags, fd, (_off64_t)off);
|
return mmap64 (addr, len, prot, flags, fd, (_off64_t)off);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* munmap () removes an mmapped area. It insists that base area
|
/* munmap () removes all mmapped pages between addr and addr+len. */
|
||||||
requested is the same as that mmapped, error if not. */
|
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
munmap (caddr_t addr, size_t len)
|
munmap (caddr_t addr, size_t len)
|
||||||
{
|
{
|
||||||
syscall_printf ("munmap (addr %x, len %d)", addr, len);
|
syscall_printf ("munmap (addr %x, len %d)", addr, len);
|
||||||
|
|
||||||
/* Error conditions according to SUSv2 */
|
/* Error conditions according to SUSv3 */
|
||||||
if (((DWORD)addr % getpagesize ()) || !len)
|
if (!addr || ((DWORD)addr % getpagesize ()) || !len
|
||||||
|
|| IsBadReadPtr (addr, len))
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
syscall_printf ("-1 = munmap(): Invalid parameters");
|
syscall_printf ("-1 = munmap(): Invalid parameters");
|
||||||
|
@ -608,17 +630,15 @@ munmap (caddr_t addr, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
SetResourceLock (LOCK_MMAP_LIST, WRITE_LOCK | READ_LOCK, "munmap");
|
SetResourceLock (LOCK_MMAP_LIST, WRITE_LOCK | READ_LOCK, "munmap");
|
||||||
/* Check if a mmap'ed area was ever created */
|
|
||||||
if (mmapped_areas == NULL)
|
if (mmapped_areas == NULL)
|
||||||
{
|
{
|
||||||
syscall_printf ("-1 = munmap(): mmapped_areas == NULL");
|
syscall_printf ("-1 = munmap(): mmapped_areas == NULL");
|
||||||
set_errno (EINVAL);
|
|
||||||
ReleaseResourceLock (LOCK_MMAP_LIST, WRITE_LOCK | READ_LOCK, "munmap");
|
ReleaseResourceLock (LOCK_MMAP_LIST, WRITE_LOCK | READ_LOCK, "munmap");
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Iterate through the map, looking for the mmapped area.
|
/* Iterate through the map, unmap pages between addr and addr+len
|
||||||
Error if not found. */
|
in all maps. */
|
||||||
|
|
||||||
for (int it = 0; it < mmapped_areas->nlists; ++it)
|
for (int it = 0; it < mmapped_areas->nlists; ++it)
|
||||||
{
|
{
|
||||||
|
@ -626,10 +646,13 @@ munmap (caddr_t addr, size_t len)
|
||||||
if (map_list)
|
if (map_list)
|
||||||
{
|
{
|
||||||
long li = -1;
|
long li = -1;
|
||||||
if ((li = map_list->match(addr, len, li)) >= 0)
|
caddr_t u_addr;
|
||||||
|
DWORD u_len;
|
||||||
|
|
||||||
|
while ((li = map_list->match(addr, len, u_addr, u_len, li)) >= 0)
|
||||||
{
|
{
|
||||||
mmap_record *rec = map_list->recs + li;
|
mmap_record *rec = map_list->recs + li;
|
||||||
if (rec->unmap_map (addr, len))
|
if (rec->unmap_map (u_addr, u_len))
|
||||||
{
|
{
|
||||||
fhandler_base *fh = rec->alloc_fh ();
|
fhandler_base *fh = rec->alloc_fh ();
|
||||||
fh->munmap (rec->get_handle (), addr, len);
|
fh->munmap (rec->get_handle (), addr, len);
|
||||||
|
@ -638,18 +661,13 @@ munmap (caddr_t addr, size_t len)
|
||||||
/* Delete the entry. */
|
/* Delete the entry. */
|
||||||
map_list->erase (li);
|
map_list->erase (li);
|
||||||
}
|
}
|
||||||
syscall_printf ("0 = munmap(): %x", addr);
|
|
||||||
ReleaseResourceLock (LOCK_MMAP_LIST, WRITE_LOCK | READ_LOCK, "munmap");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_errno (EINVAL);
|
|
||||||
syscall_printf ("-1 = munmap(): EINVAL");
|
|
||||||
|
|
||||||
ReleaseResourceLock (LOCK_MMAP_LIST, WRITE_LOCK | READ_LOCK, "munmap");
|
ReleaseResourceLock (LOCK_MMAP_LIST, WRITE_LOCK | READ_LOCK, "munmap");
|
||||||
return -1;
|
syscall_printf ("0 = munmap(): %x", addr);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sync file with memory. Ignore flags for now. */
|
/* Sync file with memory. Ignore flags for now. */
|
||||||
|
|
Loading…
Reference in New Issue