runtime_loader: randomize position of runtime_loader
* make runtime_loader a dynammically linked object * add kernel support for loading user images that need to be relocated * load runtime_loader at random address
This commit is contained in:
parent
cf35dcc5bc
commit
db1ca60528
|
@ -1069,7 +1069,7 @@ elf_resolve_symbol(struct elf_image_info *image, elf_sym *symbol,
|
|||
|
||||
/*! Until we have shared library support, just this links against the kernel */
|
||||
static int
|
||||
elf_relocate(struct elf_image_info *image)
|
||||
elf_relocate(struct elf_image_info* image, struct elf_image_info* resolveImage)
|
||||
{
|
||||
int status = B_NO_ERROR;
|
||||
|
||||
|
@ -1079,7 +1079,7 @@ elf_relocate(struct elf_image_info *image)
|
|||
if (image->rel) {
|
||||
TRACE(("total %i rel relocs\n", image->rel_len / (int)sizeof(elf_rel)));
|
||||
|
||||
status = arch_elf_relocate_rel(image, sKernelImage, image->rel,
|
||||
status = arch_elf_relocate_rel(image, resolveImage, image->rel,
|
||||
image->rel_len);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
@ -1089,12 +1089,12 @@ elf_relocate(struct elf_image_info *image)
|
|||
if (image->pltrel_type == DT_REL) {
|
||||
TRACE(("total %i plt-relocs\n",
|
||||
image->pltrel_len / (int)sizeof(elf_rel)));
|
||||
status = arch_elf_relocate_rel(image, sKernelImage, image->pltrel,
|
||||
status = arch_elf_relocate_rel(image, resolveImage, image->pltrel,
|
||||
image->pltrel_len);
|
||||
} else {
|
||||
TRACE(("total %i plt-relocs\n",
|
||||
image->pltrel_len / (int)sizeof(elf_rela)));
|
||||
status = arch_elf_relocate_rela(image, sKernelImage,
|
||||
status = arch_elf_relocate_rela(image, resolveImage,
|
||||
(elf_rela *)image->pltrel, image->pltrel_len);
|
||||
}
|
||||
if (status < B_OK)
|
||||
|
@ -1105,7 +1105,7 @@ elf_relocate(struct elf_image_info *image)
|
|||
TRACE(("total %i rel relocs\n",
|
||||
image->rela_len / (int)sizeof(elf_rela)));
|
||||
|
||||
status = arch_elf_relocate_rela(image, sKernelImage, image->rela,
|
||||
status = arch_elf_relocate_rela(image, resolveImage, image->rela,
|
||||
image->rela_len);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
@ -1288,7 +1288,7 @@ insert_preloaded_image(preloaded_elf_image *preloadedImage, bool kernel)
|
|||
if (status != B_OK)
|
||||
goto error1;
|
||||
|
||||
status = elf_relocate(image);
|
||||
status = elf_relocate(image, sKernelImage);
|
||||
if (status != B_OK)
|
||||
goto error1;
|
||||
} else
|
||||
|
@ -1825,6 +1825,8 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||
ssize_t length;
|
||||
int fd;
|
||||
int i;
|
||||
addr_t delta = 0;
|
||||
uint32 addressSpec = B_RANDOMIZED_BASE_ADDRESS;
|
||||
|
||||
TRACE(("elf_load: entry path '%s', team %p\n", path, team));
|
||||
|
||||
|
@ -1854,6 +1856,14 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||
if (status < B_OK)
|
||||
goto error;
|
||||
|
||||
struct elf_image_info* image;
|
||||
image = create_image_struct();
|
||||
if (image == NULL) {
|
||||
status = B_NO_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
image->elf_header = &elfHeader;
|
||||
|
||||
// read program header
|
||||
|
||||
programHeaders = (elf_phdr *)malloc(
|
||||
|
@ -1861,7 +1871,7 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||
if (programHeaders == NULL) {
|
||||
dprintf("error allocating space for program headers\n");
|
||||
status = B_NO_MEMORY;
|
||||
goto error;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
TRACE(("reading in program headers at 0x%lx, length 0x%x\n",
|
||||
|
@ -1871,12 +1881,12 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||
if (length < B_OK) {
|
||||
status = length;
|
||||
dprintf("error reading in program headers\n");
|
||||
goto error;
|
||||
goto error2;
|
||||
}
|
||||
if (length != elfHeader.e_phnum * elfHeader.e_phentsize) {
|
||||
dprintf("short read while reading in program headers\n");
|
||||
status = -1;
|
||||
goto error;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
// construct a nice name for the region we have to create below
|
||||
|
@ -1904,13 +1914,21 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||
for (i = 0; i < elfHeader.e_phnum; i++) {
|
||||
char regionName[B_OS_NAME_LENGTH];
|
||||
char *regionAddress;
|
||||
char *originalRegionAddress;
|
||||
area_id id;
|
||||
|
||||
if (programHeaders[i].p_type == PT_DYNAMIC) {
|
||||
image->dynamic_section = programHeaders[i].p_vaddr;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (programHeaders[i].p_type != PT_LOAD)
|
||||
continue;
|
||||
|
||||
regionAddress = (char *)ROUNDDOWN(programHeaders[i].p_vaddr,
|
||||
B_PAGE_SIZE);
|
||||
regionAddress = (char *)(ROUNDDOWN(programHeaders[i].p_vaddr,
|
||||
B_PAGE_SIZE) + delta);
|
||||
originalRegionAddress = regionAddress;
|
||||
|
||||
if (programHeaders[i].p_flags & PF_WRITE) {
|
||||
// rw/data segment
|
||||
size_t memUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE)
|
||||
|
@ -1924,18 +1942,21 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||
sprintf(regionName, "%s_seg%drw", baseName, i);
|
||||
|
||||
id = vm_map_file(team->id, regionName, (void **)®ionAddress,
|
||||
B_EXACT_ADDRESS, fileUpperBound,
|
||||
addressSpec, fileUpperBound,
|
||||
B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, false,
|
||||
fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
|
||||
if (id < B_OK) {
|
||||
dprintf("error mapping file data: %s!\n", strerror(id));
|
||||
status = B_NOT_AN_EXECUTABLE;
|
||||
goto error;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
imageInfo.data = regionAddress;
|
||||
imageInfo.data_size = memUpperBound;
|
||||
|
||||
image->data_region.start = (addr_t)regionAddress;
|
||||
image->data_region.size = memUpperBound;
|
||||
|
||||
// clean garbage brought by mmap (the region behind the file,
|
||||
// at least parts of it are the bss and have to be zeroed)
|
||||
addr_t start = (addr_t)regionAddress
|
||||
|
@ -1965,7 +1986,7 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||
if (id < B_OK) {
|
||||
dprintf("error allocating bss area: %s!\n", strerror(id));
|
||||
status = B_NOT_AN_EXECUTABLE;
|
||||
goto error;
|
||||
goto error2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1976,20 +1997,42 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||
+ (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
|
||||
|
||||
id = vm_map_file(team->id, regionName, (void **)®ionAddress,
|
||||
B_EXACT_ADDRESS, segmentSize,
|
||||
B_READ_AREA | B_EXECUTE_AREA, REGION_PRIVATE_MAP, false,
|
||||
fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
|
||||
addressSpec, segmentSize,
|
||||
B_READ_AREA | B_EXECUTE_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP,
|
||||
false, fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
|
||||
if (id < B_OK) {
|
||||
dprintf("error mapping file text: %s!\n", strerror(id));
|
||||
status = B_NOT_AN_EXECUTABLE;
|
||||
goto error;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
imageInfo.text = regionAddress;
|
||||
imageInfo.text_size = segmentSize;
|
||||
|
||||
image->text_region.start = (addr_t)regionAddress;
|
||||
image->text_region.size = segmentSize;
|
||||
}
|
||||
|
||||
if (addressSpec != B_EXACT_ADDRESS) {
|
||||
addressSpec = B_EXACT_ADDRESS;
|
||||
delta = regionAddress - originalRegionAddress;
|
||||
}
|
||||
}
|
||||
|
||||
image->data_region.delta = delta;
|
||||
image->text_region.delta = delta;
|
||||
|
||||
// modify the dynamic ptr by the delta of the regions
|
||||
image->dynamic_section += image->text_region.delta;
|
||||
|
||||
status = elf_parse_dynamic_section(image);
|
||||
if (status != B_OK)
|
||||
goto error2;
|
||||
|
||||
status = elf_relocate(image, image);
|
||||
if (status != B_OK)
|
||||
goto error2;
|
||||
|
||||
// register the loaded image
|
||||
imageInfo.type = B_LIBRARY_IMAGE;
|
||||
imageInfo.device = st.st_dev;
|
||||
|
@ -2009,9 +2052,13 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||
|
||||
TRACE(("elf_load: done!\n"));
|
||||
|
||||
*entry = elfHeader.e_entry;
|
||||
*entry = elfHeader.e_entry + delta;
|
||||
status = B_OK;
|
||||
|
||||
error2:
|
||||
image->elf_header = NULL;
|
||||
delete_elf_image(image);
|
||||
|
||||
error:
|
||||
free(programHeaders);
|
||||
_kern_close(fd);
|
||||
|
@ -2258,7 +2305,7 @@ load_kernel_add_on(const char *path)
|
|||
if (status != B_OK)
|
||||
goto error5;
|
||||
|
||||
status = elf_relocate(image);
|
||||
status = elf_relocate(image, sKernelImage);
|
||||
if (status < B_OK)
|
||||
goto error5;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ ENTRY(runtime_loader)
|
|||
SEARCH_DIR("libgcc");
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00100000 + SIZEOF_HEADERS;
|
||||
. = 0x00000000 + SIZEOF_HEADERS;
|
||||
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
|
|
|
@ -5,7 +5,7 @@ ENTRY(runtime_loader)
|
|||
SEARCH_DIR("libgcc");
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00200000 + SIZEOF_HEADERS;
|
||||
. = 0x00000000 + SIZEOF_HEADERS;
|
||||
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
|
|
|
@ -91,7 +91,7 @@ Ld runtime_loader :
|
|||
$(TARGET_STATIC_LIBSUPC++)
|
||||
$(TARGET_GCC_LIBGCC)
|
||||
: $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/runtime_loader.ld
|
||||
: --no-undefined
|
||||
: --no-undefined -shared -soname=runtime_loader
|
||||
;
|
||||
|
||||
HaikuSubInclude arch $(TARGET_ARCH) ;
|
||||
|
|
Loading…
Reference in New Issue