From ea7e2601d489bdbee0bbac8f57c934180c37f55c Mon Sep 17 00:00:00 2001 From: Jessica Hamilton Date: Mon, 21 Jul 2014 11:02:57 +1200 Subject: [PATCH] runtime_loader: only add ABI directories to system library paths It only makes sense to add the ABI directories to library paths created by Haiku itself. E.g. on a gcc2h build, appending x86. This also fixes build issues where LIBRARY_PATH is amended, and the target binaries and libraries are in different locations. Note: the develop lib directories were excluded, as runtime_loader shouldn't be looking at these in the first place. --- src/system/libroot/os/find_directory.cpp | 163 ++++++++++++++++++- src/system/runtime_loader/Jamfile | 8 +- src/system/runtime_loader/runtime_loader.cpp | 18 +- 3 files changed, 186 insertions(+), 3 deletions(-) diff --git a/src/system/libroot/os/find_directory.cpp b/src/system/libroot/os/find_directory.cpp index b9890e88bf..58a0944d7b 100644 --- a/src/system/libroot/os/find_directory.cpp +++ b/src/system/libroot/os/find_directory.cpp @@ -190,7 +190,7 @@ static const char *kUserDirectories[] = { HOME CONFIG "/var", }; - +#ifndef _LOADER_MODE /*! make dir and its parents if needed */ static int create_path(const char *path, mode_t mode) @@ -512,3 +512,164 @@ DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__find_directory_alpha4", DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__find_directory", "find_directory@@", "1_ALPHA5"); +#else +status_t +__find_directory(directory_which which, dev_t device, bool createIt, + char *returnedPath, int32 _pathLength) +{ + if (_pathLength <= 0) + return E2BIG; + size_t pathLength = _pathLength; + + const char *templatePath = NULL; + + /* as with the R5 version, no on-stack buffer */ + char *buffer = (char*)malloc(pathLength); + if (buffer == NULL) + return B_NO_MEMORY; + MemoryDeleter bufferDeleter(buffer); + + memset(buffer, 0, pathLength); + + strlcat(buffer, "/boot", pathLength); + + switch ((int)which) { + /* Haiku system directories */ + case B_SYSTEM_DIRECTORY: + case B_BEOS_SYSTEM_DIRECTORY: + case B_SYSTEM_ADDONS_DIRECTORY: + case B_SYSTEM_BOOT_DIRECTORY: + case B_SYSTEM_FONTS_DIRECTORY: + case B_SYSTEM_LIB_DIRECTORY: + case B_SYSTEM_SERVERS_DIRECTORY: + case B_SYSTEM_APPS_DIRECTORY: + case B_SYSTEM_BIN_DIRECTORY: + case B_BEOS_ETC_DIRECTORY: + case B_SYSTEM_DOCUMENTATION_DIRECTORY: + case B_SYSTEM_PREFERENCES_DIRECTORY: + case B_SYSTEM_TRANSLATORS_DIRECTORY: + case B_SYSTEM_MEDIA_NODES_DIRECTORY: + case B_SYSTEM_SOUNDS_DIRECTORY: + case B_SYSTEM_DATA_DIRECTORY: + case B_SYSTEM_DEVELOP_DIRECTORY: + case B_SYSTEM_PACKAGES_DIRECTORY: + case B_SYSTEM_HEADERS_DIRECTORY: + templatePath = kSystemDirectories[which - B_SYSTEM_DIRECTORY]; + break; + + /* Obsolete common directories and writable system directories */ + case B_COMMON_DIRECTORY: + case B_COMMON_SYSTEM_DIRECTORY: + case B_COMMON_ADDONS_DIRECTORY: + case B_COMMON_BOOT_DIRECTORY: + case B_COMMON_FONTS_DIRECTORY: + case B_COMMON_LIB_DIRECTORY: + case B_COMMON_SERVERS_DIRECTORY: + case B_COMMON_BIN_DIRECTORY: + case B_SYSTEM_ETC_DIRECTORY: + case B_COMMON_DOCUMENTATION_DIRECTORY: + case B_SYSTEM_SETTINGS_DIRECTORY: + case B_COMMON_DEVELOP_DIRECTORY: + case B_SYSTEM_LOG_DIRECTORY: + case B_SYSTEM_SPOOL_DIRECTORY: + case B_SYSTEM_TEMP_DIRECTORY: + case B_SYSTEM_VAR_DIRECTORY: + case B_COMMON_TRANSLATORS_DIRECTORY: + case B_COMMON_MEDIA_NODES_DIRECTORY: + case B_COMMON_SOUNDS_DIRECTORY: + case B_COMMON_DATA_DIRECTORY: + case B_SYSTEM_CACHE_DIRECTORY: + case B_COMMON_PACKAGES_DIRECTORY: + case B_COMMON_HEADERS_DIRECTORY: + case B_SYSTEM_NONPACKAGED_DIRECTORY: + case B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY: + case B_SYSTEM_NONPACKAGED_TRANSLATORS_DIRECTORY: + case B_SYSTEM_NONPACKAGED_MEDIA_NODES_DIRECTORY: + case B_SYSTEM_NONPACKAGED_BIN_DIRECTORY: + case B_SYSTEM_NONPACKAGED_DATA_DIRECTORY: + case B_SYSTEM_NONPACKAGED_FONTS_DIRECTORY: + case B_SYSTEM_NONPACKAGED_SOUNDS_DIRECTORY: + case B_SYSTEM_NONPACKAGED_DOCUMENTATION_DIRECTORY: + case B_SYSTEM_NONPACKAGED_LIB_DIRECTORY: + case B_SYSTEM_NONPACKAGED_HEADERS_DIRECTORY: + case B_SYSTEM_NONPACKAGED_DEVELOP_DIRECTORY: + templatePath = kCommonDirectories[which - B_COMMON_DIRECTORY]; + break; + + /* User directories */ + case B_USER_DIRECTORY: + case B_USER_CONFIG_DIRECTORY: + case B_USER_ADDONS_DIRECTORY: + case B_USER_BOOT_DIRECTORY: + case B_USER_FONTS_DIRECTORY: + case B_USER_LIB_DIRECTORY: + case B_USER_SETTINGS_DIRECTORY: + case B_USER_DESKBAR_DIRECTORY: + case B_USER_PRINTERS_DIRECTORY: + case B_USER_TRANSLATORS_DIRECTORY: + case B_USER_MEDIA_NODES_DIRECTORY: + case B_USER_SOUNDS_DIRECTORY: + case B_USER_DATA_DIRECTORY: + case B_USER_CACHE_DIRECTORY: + case B_USER_PACKAGES_DIRECTORY: + case B_USER_HEADERS_DIRECTORY: + case B_USER_DEVELOP_DIRECTORY: + case B_USER_DOCUMENTATION_DIRECTORY: + case B_USER_NONPACKAGED_DIRECTORY: + case B_USER_NONPACKAGED_ADDONS_DIRECTORY: + case B_USER_NONPACKAGED_TRANSLATORS_DIRECTORY: + case B_USER_NONPACKAGED_MEDIA_NODES_DIRECTORY: + case B_USER_NONPACKAGED_BIN_DIRECTORY: + case B_USER_NONPACKAGED_DATA_DIRECTORY: + case B_USER_NONPACKAGED_FONTS_DIRECTORY: + case B_USER_NONPACKAGED_SOUNDS_DIRECTORY: + case B_USER_NONPACKAGED_DOCUMENTATION_DIRECTORY: + case B_USER_NONPACKAGED_LIB_DIRECTORY: + case B_USER_NONPACKAGED_HEADERS_DIRECTORY: + case B_USER_NONPACKAGED_DEVELOP_DIRECTORY: + case B_USER_SERVERS_DIRECTORY: + case B_USER_APPS_DIRECTORY: + case B_USER_BIN_DIRECTORY: + case B_USER_PREFERENCES_DIRECTORY: + case B_USER_ETC_DIRECTORY: + case B_USER_LOG_DIRECTORY: + case B_USER_SPOOL_DIRECTORY: + case B_USER_VAR_DIRECTORY: + templatePath = kUserDirectories[which - B_USER_DIRECTORY]; + break; + + default: + return EINVAL; + } + + if (templatePath == NULL) + return ENOENT; + + PathBuffer pathBuffer(buffer, pathLength, strlen(buffer)); + + // resolve "$h" placeholder to the user's home directory + if (!strncmp(templatePath, "$h", 2)) { + pathBuffer.Append("/home"); + templatePath += 2; + } else if (templatePath[0] != '\0') + pathBuffer.Append('/'); + + // resolve "$a" placeholder to the architecture subdirectory, if not + // primary + if (char* dollar = strchr(templatePath, '$')) { + if (dollar[1] == 'a') { + pathBuffer.Append(templatePath, dollar - templatePath); + templatePath = dollar + 2; + } + } + + // append (remainder of) template path + pathBuffer.Append(templatePath); + + if (pathBuffer.Length() >= pathLength) + return E2BIG; + + strlcpy(returnedPath, buffer, pathLength); + return B_OK; +} +#endif diff --git a/src/system/runtime_loader/Jamfile b/src/system/runtime_loader/Jamfile index eee444b358..315aa139c4 100644 --- a/src/system/runtime_loader/Jamfile +++ b/src/system/runtime_loader/Jamfile @@ -5,8 +5,12 @@ local architecture = $(TARGET_PACKAGING_ARCH) ; UsePrivateHeaders libroot runtime_loader shared ; UsePrivateHeaders kernel ; # for +UsePrivateHeaders libroot os ; + # for "PathBuffer.h" UsePrivateSystemHeaders ; +ObjectHdrs find_directory.cpp : $(HAIKU_TOP)/src/system/libroot/os ; + # Don't let gcc inject built-in function code. This will cause dependencies # to libroot, which we don't link against. SubDirCcFlags -fno-builtin ; @@ -25,6 +29,7 @@ StaticLibrary libruntime_loader.a : kernel_vsprintf.cpp kernel_cpp.cpp KMessage.cpp + find_directory.cpp : mutex.o recursive_lock.o @@ -68,7 +73,8 @@ SEARCH on [ FGristFiles kernel_vsprintf.cpp ] = [ FDirName $(HAIKU_TOP) src system kernel lib ] ; SEARCH on [ FGristFiles KMessage.cpp ] = [ FDirName $(HAIKU_TOP) src system kernel messaging ] ; - +SEARCH on [ FGristFiles find_directory.cpp ] + = [ FDirName $(HAIKU_TOP) src system libroot os ] ; local sources = add_ons.cpp diff --git a/src/system/runtime_loader/runtime_loader.cpp b/src/system/runtime_loader/runtime_loader.cpp index 16bb18fde2..46c25dfc22 100644 --- a/src/system/runtime_loader/runtime_loader.cpp +++ b/src/system/runtime_loader/runtime_loader.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -33,6 +34,13 @@ void *__dso_handle; int32 __gCPUCount = 1; +const directory_which kLibraryDirectories[] = { + B_SYSTEM_LIB_DIRECTORY, + B_SYSTEM_NONPACKAGED_LIB_DIRECTORY, + B_USER_LIB_DIRECTORY, + B_USER_NONPACKAGED_LIB_DIRECTORY +}; + static const char * search_path_for_type(image_type type) @@ -175,7 +183,15 @@ try_open_executable(const char *dir, int dirLength, const char *name, // not been compiled with a compiler using the same ABI as the one // the OS has been built with. Thus we only look in subdirs // specific to that ABI. - subDirLen = strlen(abiSpecificSubDir) + 1; + // However, only if it's a known library location + for (int i = 0; i < 4; ++i) { + char buffer[PATH_MAX]; + __find_directory(kLibraryDirectories[i], -1, false, buffer, PATH_MAX); + if (strncmp(dir, buffer, dirLength) == 0) { + subDirLen = strlen(abiSpecificSubDir) + 1; + break; + } + } } if (dirLength + 1 + subDirLen + nameLength >= pathLength)