runtime_loader: Randomly position only relocatable code

The use of an unreliable test for relocatability effectively broke
runtime_loader's support for non-position-independent executables, as it
would insist on randomly positioning these files' segments in memory
anyway causing the program to quickly crash.

With this change runtime_loader uses the object type specified in the
file's header to determine whether its segments can be safely relocated,
restoring support for non-PI executables.

Fixes #12427.

Signed-off-by: Adrien Destugues <[email protected]>
This commit is contained in:
Simon South
2015-10-26 21:19:25 +01:00
committed by Adrien Destugues
parent 1e6dd3feed
commit 078b88b12d
4 changed files with 24 additions and 7 deletions
+11
View File
@@ -31,6 +31,17 @@
#define EI_VERSION 6
#define EI_PAD 7
// e_type (Object file type)
#define ET_NONE 0 // No file type
#define ET_REL 1 // Relocatable file
#define ET_EXEC 2 // Executable file
#define ET_DYN 3 // Shared object file
#define ET_CORE 4 // Core file
#define ET_LOOS 0xfe00 // OS-specific range start
#define ET_HIOS 0xfeff // OS-specific range end
#define ET_LOPROC 0xff00 // Processor-specific range start
#define ET_HIPROC 0xffff // Processor-specific range end
// e_machine (Architecture)
#define EM_NONE 0 // No machine
#define EM_M32 1 // AT&T WE 32100
+1 -1
View File
@@ -527,7 +527,7 @@ load_image(char const* name, image_type type, const char* rpath,
goto err2;
}
status = map_image(fd, path, image);
status = map_image(fd, path, image, eheader.e_type == ET_EXEC);
if (status < B_OK) {
FATAL("%s: Could not map image: %s\n", image->path, strerror(status));
status = B_ERROR;
+11 -5
View File
@@ -169,9 +169,9 @@ topological_sort(image_t* image, uint32 slot, image_t** initList,
*/
static void
get_image_region_load_address(image_t* image, uint32 index, long lastDelta,
addr_t& loadAddress, uint32& addressSpecifier)
bool fixed, addr_t& loadAddress, uint32& addressSpecifier)
{
if (image->dynamic_ptr != 0) {
if (!fixed) {
// relocatable image... we can afford to place wherever
if (index == 0) {
// but only the first segment gets a free ride
@@ -286,7 +286,7 @@ put_image(image_t* image)
status_t
map_image(int fd, char const* path, image_t* image)
map_image(int fd, char const* path, image_t* image, bool fixed)
{
// cut the file name from the path as base name for the created areas
const char* baseName = strrchr(path, '/');
@@ -304,10 +304,16 @@ map_image(int fd, char const* path, image_t* image)
uint32 addressSpecifier = B_RANDOMIZED_ANY_ADDRESS;
for (uint32 i = 0; i < image->num_regions; i++) {
// for BeOS compatibility: if we load an old BeOS executable, we
// have to relocate it, if possible - we recognize it because the
// vmstart is set to 0 (hopefully always)
if (fixed && image->regions[i].vmstart == 0)
fixed = false;
uint32 regionAddressSpecifier;
get_image_region_load_address(image, i,
i > 0 ? loadAddress - image->regions[i - 1].vmstart : 0,
loadAddress, regionAddressSpecifier);
fixed, loadAddress, regionAddressSpecifier);
if (i == 0) {
reservedAddress = loadAddress;
addressSpecifier = regionAddressSpecifier;
@@ -339,7 +345,7 @@ map_image(int fd, char const* path, image_t* image)
baseName, i, (image->regions[i].flags & RFLAG_RW) ? "rw" : "ro");
get_image_region_load_address(image, i,
i > 0 ? image->regions[i - 1].delta : 0, loadAddress,
i > 0 ? image->regions[i - 1].delta : 0, fixed, loadAddress,
addressSpecifier);
// If the image position is arbitrary, we must let it point to the start
+1 -1
View File
@@ -50,7 +50,7 @@ void delete_image_struct(image_t* image);
void delete_image(image_t* image);
void put_image(image_t* image);
status_t map_image(int fd, char const* path, image_t* image);
status_t map_image(int fd, char const* path, image_t* image, bool fixed);
void unmap_image(image_t* image);
void remap_images();