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:
committed by
Adrien Destugues
parent
1e6dd3feed
commit
078b88b12d
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user