diff --git a/headers/private/system/elf_common.h b/headers/private/system/elf_common.h index 3e65305563..23ab555032 100644 --- a/headers/private/system/elf_common.h +++ b/headers/private/system/elf_common.h @@ -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 diff --git a/src/system/runtime_loader/elf_load_image.cpp b/src/system/runtime_loader/elf_load_image.cpp index cfa4e34fcf..8455645a60 100644 --- a/src/system/runtime_loader/elf_load_image.cpp +++ b/src/system/runtime_loader/elf_load_image.cpp @@ -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; diff --git a/src/system/runtime_loader/images.cpp b/src/system/runtime_loader/images.cpp index d851f9fd06..2b7f6dfe8c 100644 --- a/src/system/runtime_loader/images.cpp +++ b/src/system/runtime_loader/images.cpp @@ -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 diff --git a/src/system/runtime_loader/images.h b/src/system/runtime_loader/images.h index 7a309bb6c8..a929040b42 100644 --- a/src/system/runtime_loader/images.h +++ b/src/system/runtime_loader/images.h @@ -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();