Fixed various faults with execve().

Added a new ordered task_insert_vma() function
This commit is contained in:
Bahadir Balban
2008-12-02 14:15:40 +02:00
parent 05d8438f34
commit 32b3dfe91d
7 changed files with 68 additions and 7 deletions

View File

@@ -21,6 +21,7 @@ static inline void __attribute__ ((noreturn)) l4_exit(int status)
void __attribute__ ((noreturn)) _exit(int status)
{
printf("In %s.\n", __FUNCTION__);
l4_exit(status);
}

View File

@@ -248,10 +248,7 @@ int validate_task_range(struct tcb *t, unsigned long start,
/* Changes all shadows and their ptes to read-only */
int vm_freeze_shadows(struct tcb *task);
static inline void task_add_vma(struct tcb *task, struct vm_area *vma)
{
list_add(&vma->list, &task->vm_area_head->list);
}
int task_insert_vma(struct vm_area *vma, struct list_head *vma_list);
/* Main page fault entry point */
int page_fault_handler(struct tcb *faulty_task, fault_kdata_t *fkdata);

View File

@@ -225,7 +225,8 @@ int strncpy_page(void *to_ptr, void *from_ptr, int maxlength)
/*
* Copy from one buffer to another. Stop if maxlength or
* a page boundary is hit. Breaks if unsigned long sized copy value is 0,
* as opposed to a 0 byte as in string copy.
* as opposed to a 0 byte as in string copy. If byte size 0 was used
* a valid pointer with a 0 byte in it would give a false termination.
*/
int bufncpy_page(void *to_ptr, void *from_ptr, int maxlength)
{

View File

@@ -243,6 +243,7 @@ int file_open(struct tcb *opener, int fd)
return 0;
}
/*
* Inserts the page to vmfile's list in order of page frame offset.
* We use an ordered list instead of a better data structure for now.

View File

@@ -38,6 +38,65 @@ struct vm_area *vma_new(unsigned long pfn_start, unsigned long npages,
return vma;
}
/*
* Inserts a new vma to the ordered vm area list.
*
* The new vma is assumed to have been correctly set up not to intersect
* with any other existing vma.
*/
int task_insert_vma(struct vm_area *this, struct list_head *vma_list)
{
struct vm_area *before, *after;
/* Add if list is empty */
if (list_empty(vma_list)) {
list_add_tail(&this->list, vma_list);
return 0;
}
/* Else find the right interval */
list_for_each_entry(before, vma_list, list) {
after = list_entry(before->list.next, struct vm_area, list);
/* If there's only one in list */
if (before->list.next == vma_list) {
/* Eliminate the possibility of intersection */
BUG_ON(set_intersection(this->pfn_start, this->pfn_end,
before->pfn_start,
before->pfn_end));
/* Add as next if greater */
if (this->pfn_start > before->pfn_start)
list_add(&this->list, &before->list);
/* Add as previous if smaller */
else if (this->pfn_start < before->pfn_start)
list_add_tail(&this->list, &before->list);
else
BUG();
return 0;
}
/* If this page is in-between two other, insert it there */
if (before->pfn_start < this->pfn_start &&
after->pfn_start > this->pfn_start) {
/* Eliminate possibility of intersection */
BUG_ON(set_intersection(this->pfn_start, this->pfn_end,
before->pfn_start,
before->pfn_end));
BUG_ON(set_intersection(this->pfn_start, this->pfn_end,
after->pfn_start,
after->pfn_end));
list_add(&this->list, &before->list);
return 0;
}
}
BUG();
}
/* Search an empty space in the task's mmapable address region. */
unsigned long find_unmapped_area(unsigned long npages, struct tcb *task)
{
@@ -234,7 +293,7 @@ void *do_mmap(struct vm_file *mapfile, unsigned long file_offset,
/* Finished initialising the vma, add it to task */
dprintf("%s: Mapping 0x%x - 0x%x\n", __FUNCTION__,
map_address, map_address + __pfn_to_addr(npages));
task_add_vma(task, new);
task_insert_vma(new, &task->vm_area_head->list);
/*
* If area is going to be used going downwards, (i.e. as a stack)

View File

@@ -194,7 +194,7 @@ int task_copy_vmas(struct tcb *to, struct tcb *from)
vma_copy_links(new_vma, vma);
/* All link copying is finished, now add the new vma to task */
task_add_vma(to, new_vma);
task_insert_vma(new_vma, &to->vm_area_head->list);
}
return 0;

View File

@@ -21,12 +21,14 @@ int forktest(void)
myid = getpid();
pid = myid;
if (global != 0) {
printf("Global not zero.\n");
printf("-- FAILED --\n");
goto out;
}
global = myid;
if (global != myid) {
printf("Global has not changed to myid.\n");
printf("-- FAILED --\n");
goto out;
}