Revision f19412a2
b/linux-user/mmap.c | ||
---|---|---|
537 | 537 |
return ret; |
538 | 538 |
} |
539 | 539 |
|
540 |
/* XXX: currently, we only handle MAP_ANONYMOUS and not MAP_FIXED |
|
541 |
blocks which have been allocated starting on a host page */ |
|
542 | 540 |
abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, |
543 | 541 |
abi_ulong new_size, unsigned long flags, |
544 | 542 |
abi_ulong new_addr) |
545 | 543 |
{ |
546 | 544 |
int prot; |
547 |
unsigned long host_addr;
|
|
545 |
void *host_addr;
|
|
548 | 546 |
|
549 | 547 |
mmap_lock(); |
550 |
/* XXX: use 5 args syscall */ |
|
551 |
host_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags); |
|
552 |
if (host_addr == -1) { |
|
548 |
|
|
549 |
if (flags & MREMAP_FIXED) |
|
550 |
host_addr = mremap(g2h(old_addr), old_size, new_size, |
|
551 |
flags, new_addr); |
|
552 |
else if (flags & MREMAP_MAYMOVE) { |
|
553 |
abi_ulong mmap_start; |
|
554 |
|
|
555 |
mmap_start = mmap_find_vma(0, new_size); |
|
556 |
|
|
557 |
if (mmap_start == -1) { |
|
558 |
errno = ENOMEM; |
|
559 |
host_addr = MAP_FAILED; |
|
560 |
} else |
|
561 |
host_addr = mremap(g2h(old_addr), old_size, new_size, |
|
562 |
flags | MREMAP_FIXED, g2h(mmap_start)); |
|
563 |
} else { |
|
564 |
host_addr = mremap(g2h(old_addr), old_size, new_size, flags); |
|
565 |
/* Check if address fits target address space */ |
|
566 |
if ((unsigned long)host_addr + new_size > (abi_ulong)-1) { |
|
567 |
/* Revert mremap() changes */ |
|
568 |
host_addr = mremap(g2h(old_addr), new_size, old_size, flags); |
|
569 |
errno = ENOMEM; |
|
570 |
host_addr = MAP_FAILED; |
|
571 |
} |
|
572 |
} |
|
573 |
|
|
574 |
if (host_addr == MAP_FAILED) { |
|
553 | 575 |
new_addr = -1; |
554 | 576 |
} else { |
555 | 577 |
new_addr = h2g(host_addr); |
Also available in: Unified diff