Modified load_kernel_add_on() to use the new address range reservation functions.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7876 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+40
-13
@@ -1168,6 +1168,9 @@ load_kernel_add_on(const char *path)
|
|||||||
struct Elf32_Phdr *pheaders;
|
struct Elf32_Phdr *pheaders;
|
||||||
struct elf_image_info *image;
|
struct elf_image_info *image;
|
||||||
void *vnode = NULL;
|
void *vnode = NULL;
|
||||||
|
void *reservedAddress;
|
||||||
|
addr_t start;
|
||||||
|
size_t reservedSize;
|
||||||
int fd;
|
int fd;
|
||||||
int err;
|
int err;
|
||||||
int i;
|
int i;
|
||||||
@@ -1244,8 +1247,26 @@ load_kernel_add_on(const char *path)
|
|||||||
goto error3;
|
goto error3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// determine how much space we need for all loaded segments
|
||||||
|
|
||||||
|
reservedSize = 0;
|
||||||
|
|
||||||
for (i = 0; i < eheader->e_phnum; i++) {
|
for (i = 0; i < eheader->e_phnum; i++) {
|
||||||
char region_name[64];
|
if (pheaders[i].p_type != PT_LOAD)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
reservedSize += ROUNDUP(pheaders[i].p_memsz + (pheaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reserve that space and allocate the areas from that one
|
||||||
|
if (vm_reserve_address_range(vm_get_kernel_aspace_id(), &reservedAddress,
|
||||||
|
B_ANY_KERNEL_ADDRESS, reservedSize) < B_OK)
|
||||||
|
goto error3;
|
||||||
|
|
||||||
|
start = (addr_t)reservedAddress;
|
||||||
|
|
||||||
|
for (i = 0; i < eheader->e_phnum; i++) {
|
||||||
|
char regionName[B_OS_NAME_LENGTH];
|
||||||
int image_region;
|
int image_region;
|
||||||
int protection;
|
int protection;
|
||||||
|
|
||||||
@@ -1272,7 +1293,7 @@ load_kernel_add_on(const char *path)
|
|||||||
rw_segment_handled = true;
|
rw_segment_handled = true;
|
||||||
image_region = 1;
|
image_region = 1;
|
||||||
protection = B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA;
|
protection = B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA;
|
||||||
sprintf(region_name, "%s_data", path);
|
snprintf(regionName, B_OS_NAME_LENGTH, "%s_data", path);
|
||||||
} else if ((pheaders[i].p_flags & (PF_PROTECTION_MASK)) == (PF_READ | PF_EXECUTE)) {
|
} else if ((pheaders[i].p_flags & (PF_PROTECTION_MASK)) == (PF_READ | PF_EXECUTE)) {
|
||||||
// this is the non-writable segment
|
// this is the non-writable segment
|
||||||
if (ro_segment_handled) {
|
if (ro_segment_handled) {
|
||||||
@@ -1286,22 +1307,26 @@ load_kernel_add_on(const char *path)
|
|||||||
// so it has to be writeable at this point;
|
// so it has to be writeable at this point;
|
||||||
// ToDo: we should change the area protection later.
|
// ToDo: we should change the area protection later.
|
||||||
|
|
||||||
sprintf(region_name, "%s_text", path);
|
snprintf(regionName, B_OS_NAME_LENGTH, "%s_text", path);
|
||||||
} else {
|
} else {
|
||||||
dprintf("weird program header flags 0x%lx\n", pheaders[i].p_flags);
|
dprintf("weird program header flags 0x%lx\n", pheaders[i].p_flags);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDo: this won't work if the on-disk order of the sections doesn't
|
||||||
|
// fit the in-memory order...
|
||||||
|
image->regions[image_region].start = start;
|
||||||
image->regions[image_region].size = ROUNDUP(pheaders[i].p_memsz + (pheaders[i].p_vaddr % PAGE_SIZE), PAGE_SIZE);
|
image->regions[image_region].size = ROUNDUP(pheaders[i].p_memsz + (pheaders[i].p_vaddr % PAGE_SIZE), PAGE_SIZE);
|
||||||
image->regions[image_region].id = create_area(region_name,
|
image->regions[image_region].id = create_area(regionName,
|
||||||
(void **)&image->regions[image_region].start, B_ANY_KERNEL_ADDRESS,
|
(void **)&image->regions[image_region].start, B_EXACT_ADDRESS,
|
||||||
image->regions[image_region].size, B_FULL_LOCK, protection);
|
image->regions[image_region].size, B_FULL_LOCK, protection);
|
||||||
if (image->regions[image_region].id < 0) {
|
if (image->regions[image_region].id < 0) {
|
||||||
dprintf("error allocating region!\n");
|
dprintf("error allocating region!\n");
|
||||||
err = B_NOT_AN_EXECUTABLE;
|
err = B_NOT_AN_EXECUTABLE;
|
||||||
goto error3;
|
goto error4;
|
||||||
}
|
}
|
||||||
image->regions[image_region].delta = image->regions[image_region].start - ROUNDOWN(pheaders[i].p_vaddr, PAGE_SIZE);
|
image->regions[image_region].delta = image->regions[image_region].start - ROUNDOWN(pheaders[i].p_vaddr, PAGE_SIZE);
|
||||||
|
start += image->regions[image_region].size;
|
||||||
|
|
||||||
TRACE(("elf_load_kspace: created a region at %p\n", (void *)image->regions[image_region].start));
|
TRACE(("elf_load_kspace: created a region at %p\n", (void *)image->regions[image_region].start));
|
||||||
|
|
||||||
@@ -1311,16 +1336,16 @@ load_kernel_add_on(const char *path)
|
|||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
err = len;
|
err = len;
|
||||||
dprintf("error reading in seg %d\n", i);
|
dprintf("error reading in seg %d\n", i);
|
||||||
goto error4;
|
goto error5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image->regions[1].start != 0
|
if (image->regions[1].start != 0
|
||||||
&& image->regions[0].delta != image->regions[1].delta) {
|
&& image->regions[0].delta != image->regions[1].delta) {
|
||||||
dprintf("could not load binary, fix the region problem!\n");
|
dprintf("deltas do not match!\n");
|
||||||
dump_image_info(image);
|
dump_image_info(image);
|
||||||
err = B_NO_MEMORY;
|
err = B_ERROR;
|
||||||
goto error4;
|
goto error5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// modify the dynamic ptr by the delta of the regions
|
// modify the dynamic ptr by the delta of the regions
|
||||||
@@ -1328,11 +1353,11 @@ load_kernel_add_on(const char *path)
|
|||||||
|
|
||||||
err = elf_parse_dynamic_section(image);
|
err = elf_parse_dynamic_section(image);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error4;
|
goto error5;
|
||||||
|
|
||||||
err = elf_relocate(image, "");
|
err = elf_relocate(image, "");
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error4;
|
goto error5;
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
@@ -1350,11 +1375,13 @@ done:
|
|||||||
|
|
||||||
return image->id;
|
return image->id;
|
||||||
|
|
||||||
error4:
|
error5:
|
||||||
if (image->regions[1].id >= 0)
|
if (image->regions[1].id >= 0)
|
||||||
delete_area(image->regions[1].id);
|
delete_area(image->regions[1].id);
|
||||||
if (image->regions[0].id >= 0)
|
if (image->regions[0].id >= 0)
|
||||||
delete_area(image->regions[0].id);
|
delete_area(image->regions[0].id);
|
||||||
|
error4:
|
||||||
|
vm_unreserve_address_range(vm_get_kernel_aspace_id(), reservedAddress, reservedSize);
|
||||||
error3:
|
error3:
|
||||||
free(pheaders);
|
free(pheaders);
|
||||||
error2:
|
error2:
|
||||||
|
|||||||
Reference in New Issue
Block a user