Esempio n. 1
0
static void sys_brk(TrapFrame *tf) {
    tf->eax = 0;
#ifdef IA32_PAGE
    if (tf->ebx) {
    	mm_brk(tf->ebx);
    } else {
        tf->eax = mm_brk(0);
    }
#endif
    printk("brk(0x%08x) = 0x%08x\n", tf->ebx, tf->eax);
}
Esempio n. 2
0
// do_brk - adjust(increase/decrease) the size of process heap, align with page size
// NOTE: will change the process vma
int
do_brk(uintptr_t *brk_store) {
    struct mm_struct *mm = current->mm;
    if (mm == NULL) {
        panic("kernel thread call sys_brk!!.\n");
    }
    if (brk_store == NULL) {
        return -E_INVAL;
    }

    uintptr_t brk;

    lock_mm(mm);
    if (!copy_from_user(mm, &brk, brk_store, sizeof(uintptr_t), 1)) {
        unlock_mm(mm);
        return -E_INVAL;
    }

    if (brk < mm->brk_start) {
        goto out_unlock;
    }
    uintptr_t newbrk = ROUNDUP(brk, PGSIZE), oldbrk = mm->brk;
    assert(oldbrk % PGSIZE == 0);
    if (newbrk == oldbrk) {
        goto out_unlock;
    }
    if (newbrk < oldbrk) {
        if (mm_unmap(mm, newbrk, oldbrk - newbrk) != 0) {
            goto out_unlock;
        }
    }
    else {
        if (find_vma_intersection(mm, oldbrk, newbrk + PGSIZE) != NULL) {
            goto out_unlock;
        }
        if (mm_brk(mm, oldbrk, newbrk - oldbrk) != 0) {
            goto out_unlock;
        }
    }
    mm->brk = newbrk;
out_unlock:
	copy_to_user (mm, brk_store, &mm->brk, sizeof (uintptr_t));
    unlock_mm(mm);
    return 0;
}
Esempio n. 3
0
/* poring from linux */
int do_linux_brk(uintptr_t brk)
{
	uint32_t newbrk, oldbrk, retval;
	struct mm_struct *mm = current->mm;
	uint32_t min_brk;

	if (!mm) {
		panic("kernel thread call sys_brk!!.\n");
	}

	lock_mm(mm);

	min_brk = mm->brk_start;

	if (brk < min_brk)
		goto out_unlock;

	newbrk = ROUNDUP(brk, PGSIZE);
	oldbrk = ROUNDUP(mm->brk, PGSIZE);

	if (oldbrk == newbrk)
		goto set_brk;

	if (brk <= mm->brk) {
		if (!mm_unmap(mm, newbrk, oldbrk - newbrk))
			goto set_brk;
		goto out_unlock;
	}

	if (find_vma_intersection(mm, oldbrk, newbrk + PGSIZE))
		goto out_unlock;

	/* set the brk */
	if (mm_brk(mm, oldbrk, newbrk - oldbrk))
		goto out_unlock;

set_brk:
	mm->brk = brk;
out_unlock:
	retval = mm->brk;
	unlock_mm(mm);
	return retval;
}
Esempio n. 4
0
/* from x86 bionic porting */
int
do_linux_brk(uintptr_t brk) {
    struct mm_struct *mm = current->mm;
    if (mm == NULL) {
        panic("kernel thread call sys_brk!!.\n");
    }

    if (brk == 0) {
        return mm->brk_start;
    }

    lock_mm(mm);
    if (brk < mm->brk_start) {
        goto out_unlock;
    }
    uintptr_t newbrk = ROUNDUP(brk, PGSIZE), oldbrk = mm->brk;
    assert(oldbrk % PGSIZE == 0);
    if (newbrk == oldbrk) {
        goto out_unlock;
    }
    if (newbrk < oldbrk) {
        if (mm_unmap(mm, newbrk, oldbrk - newbrk) != 0) {
            goto out_unlock;
        }
    }
    else {
        if (find_vma_intersection(mm, oldbrk, newbrk + PGSIZE) != NULL) {
            goto out_unlock;
        }
        if (mm_brk(mm, oldbrk, newbrk - oldbrk) != 0) {
            goto out_unlock;
        }
    }
    mm->brk = newbrk;
out_unlock:
    unlock_mm(mm);
    return newbrk;
}
Esempio n. 5
0
static void sys_brk(TrapFrame *tf) {
#ifdef IA32_PAGE
    mm_brk(tf->ebx);
#endif
    tf->eax = 0;
}