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