Added explicit support for loading executables compiled with the
respectively other gcc version on a Haiku compiled with gcc 2 or gcc 4. The libraries for such an executable are first searched in "gcc4" respectively "gcc2" subdirectories of the standard search path directories. If not found there, we try again with the standard paths. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25532 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
b3d6c12dbf
commit
61b37794a4
@ -81,6 +81,7 @@ static uint32 sLoadedImageCount = 0;
|
||||
static image_t *sProgramImage;
|
||||
static KMessage sErrorMessage;
|
||||
static bool sProgramLoaded = false;
|
||||
static const char *sSearchPathSubDir = NULL;
|
||||
|
||||
// a recursive lock
|
||||
static sem_id rld_sem;
|
||||
@ -1192,8 +1193,9 @@ load_container(char const *name, image_type type, const char *rpath, image_t **_
|
||||
|
||||
strlcpy(path, name, sizeof(path));
|
||||
|
||||
// Try to load explicit image path first
|
||||
fd = open_executable(path, type, rpath, get_program_path());
|
||||
// find and open the file
|
||||
fd = open_executable(path, type, rpath, get_program_path(),
|
||||
sSearchPathSubDir);
|
||||
if (fd < 0) {
|
||||
FATAL("cannot open file %s\n", path);
|
||||
KTRACE("rld: load_container(\"%s\"): failed to open file", name);
|
||||
@ -1270,8 +1272,20 @@ load_container(char const *name, image_type type, const char *rpath, image_t **_
|
||||
goto err2;
|
||||
}
|
||||
|
||||
if (!analyze_object_gcc_version(fd, image, eheader, sheaderSize, ph_buff,
|
||||
if (analyze_object_gcc_version(fd, image, eheader, sheaderSize, ph_buff,
|
||||
sizeof(ph_buff))) {
|
||||
// If this is the executable image, we init the search path
|
||||
// subdir, if the compiler version doesn't match ours.
|
||||
if (type == B_APP_IMAGE) {
|
||||
#if __GNUC__ == 2
|
||||
if (image->gcc_version.major > 2)
|
||||
sSearchPathSubDir = "gcc4";
|
||||
#elif __GNUC__ == 4
|
||||
if (image->gcc_version.major == 2)
|
||||
sSearchPathSubDir = "gcc2";
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
FATAL("Failed to get gcc version for %s\n", path);
|
||||
// not really fatal, actually
|
||||
}
|
||||
|
@ -90,7 +90,8 @@ search_path_for_type(image_type type)
|
||||
|
||||
static int
|
||||
try_open_executable(const char *dir, int dirLength, const char *name,
|
||||
const char *programPath, char *path, size_t pathLength)
|
||||
const char *programPath, const char *compatibilitySubDir, char *path,
|
||||
size_t pathLength)
|
||||
{
|
||||
size_t nameLength = strlen(name);
|
||||
struct stat stat;
|
||||
@ -99,6 +100,7 @@ try_open_executable(const char *dir, int dirLength, const char *name,
|
||||
// construct the path
|
||||
if (dirLength > 0) {
|
||||
char *buffer = path;
|
||||
size_t subDirLen = 0;
|
||||
|
||||
if (programPath == NULL)
|
||||
programPath = gProgramArgs->program_path;
|
||||
@ -121,14 +123,23 @@ try_open_executable(const char *dir, int dirLength, const char *name,
|
||||
pathLength -= bytesCopied;
|
||||
dir += 2;
|
||||
dirLength -= 2;
|
||||
} else if (compatibilitySubDir != NULL) {
|
||||
// We're looking for a library or an add-on and the executable has
|
||||
// not been compiled with a compiler compatible with the one the
|
||||
// OS has been built with. Thus we only look in specific subdirs.
|
||||
subDirLen = strlen(compatibilitySubDir) + 1;
|
||||
}
|
||||
|
||||
if (dirLength + 1 + nameLength >= pathLength)
|
||||
if (dirLength + 1 + subDirLen + nameLength >= pathLength)
|
||||
return B_NAME_TOO_LONG;
|
||||
|
||||
memcpy(buffer, dir, dirLength);
|
||||
buffer[dirLength] = '/';
|
||||
strcpy(buffer + dirLength + 1, name);
|
||||
if (subDirLen > 0) {
|
||||
memcpy(buffer + dirLength + 1, compatibilitySubDir, subDirLen - 1);
|
||||
buffer[dirLength + subDirLen] = '/';
|
||||
}
|
||||
strcpy(buffer + dirLength + 1 + subDirLen, name);
|
||||
} else {
|
||||
if (nameLength >= pathLength)
|
||||
return B_NAME_TOO_LONG;
|
||||
@ -169,8 +180,8 @@ try_open_executable(const char *dir, int dirLength, const char *name,
|
||||
|
||||
static int
|
||||
search_executable_in_path_list(const char *name, const char *pathList,
|
||||
int pathListLen, const char *programPath, char *pathBuffer,
|
||||
size_t pathBufferLength)
|
||||
int pathListLen, const char *programPath, const char *compatibilitySubDir,
|
||||
char *pathBuffer, size_t pathBufferLength)
|
||||
{
|
||||
const char *pathListEnd = pathList + pathListLen;
|
||||
status_t status = B_ENTRY_NOT_FOUND;
|
||||
@ -187,7 +198,7 @@ search_executable_in_path_list(const char *name, const char *pathList,
|
||||
pathEnd++;
|
||||
|
||||
fd = try_open_executable(pathList, pathEnd - pathList, name,
|
||||
programPath, pathBuffer, pathBufferLength);
|
||||
programPath, compatibilitySubDir, pathBuffer, pathBufferLength);
|
||||
if (fd >= 0) {
|
||||
// see if it's a dir
|
||||
struct stat stat;
|
||||
@ -210,7 +221,7 @@ search_executable_in_path_list(const char *name, const char *pathList,
|
||||
|
||||
int
|
||||
open_executable(char *name, image_type type, const char *rpath,
|
||||
const char *programPath)
|
||||
const char *programPath, const char *compatibilitySubDir)
|
||||
{
|
||||
const char *paths;
|
||||
char buffer[PATH_MAX];
|
||||
@ -240,11 +251,12 @@ open_executable(char *name, image_type type, const char *rpath,
|
||||
// If there is no ';', we set only secondList to simplify things.
|
||||
if (firstList) {
|
||||
fd = search_executable_in_path_list(name, firstList,
|
||||
semicolon - firstList, programPath, buffer, sizeof(buffer));
|
||||
semicolon - firstList, programPath, NULL, buffer,
|
||||
sizeof(buffer));
|
||||
}
|
||||
if (fd < 0) {
|
||||
fd = search_executable_in_path_list(name, secondList,
|
||||
strlen(secondList), programPath, buffer, sizeof(buffer));
|
||||
strlen(secondList), programPath, NULL, buffer, sizeof(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,7 +265,14 @@ open_executable(char *name, image_type type, const char *rpath,
|
||||
paths = search_path_for_type(type);
|
||||
if (paths) {
|
||||
fd = search_executable_in_path_list(name, paths, strlen(paths),
|
||||
programPath, buffer, sizeof(buffer));
|
||||
programPath, compatibilitySubDir, buffer, sizeof(buffer));
|
||||
|
||||
// If not found and a compatibility sub directory has been
|
||||
// specified, look again in the standard search paths.
|
||||
if (fd == B_ENTRY_NOT_FOUND && compatibilitySubDir != NULL) {
|
||||
fd = search_executable_in_path_list(name, paths, strlen(paths),
|
||||
programPath, NULL, buffer, sizeof(buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,7 +307,7 @@ test_executable(const char *name, char *invoker)
|
||||
|
||||
strlcpy(path, name, sizeof(path));
|
||||
|
||||
fd = open_executable(path, B_APP_IMAGE, NULL, NULL);
|
||||
fd = open_executable(path, B_APP_IMAGE, NULL, NULL, NULL);
|
||||
if (fd < B_OK)
|
||||
return fd;
|
||||
|
||||
|
@ -24,7 +24,7 @@ extern "C" {
|
||||
|
||||
int runtime_loader(void *arg);
|
||||
int open_executable(char *name, image_type type, const char *rpath,
|
||||
const char *programPath);
|
||||
const char *programPath, const char *compatibilitySubDir);
|
||||
status_t test_executable(const char *path, char *interpreter);
|
||||
|
||||
void terminate_program(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user