#include "crazy_linker_library_list.h"
+#include <assert.h>
+#include <crazy_linker.h>
#include <dlfcn.h>
#include "crazy_linker_debug.h"
namespace {
+// Page size for alignment in a zip file.
+const size_t kZipAlignmentPageSize = 4096;
+static_assert(kZipAlignmentPageSize % PAGE_SIZE == 0,
+ "kZipAlignmentPageSize must be a multiple of PAGE_SIZE");
+
// A helper struct used when looking up symbols in libraries.
struct SymbolLookupState {
void* found_addr;
uintptr_t load_address,
off_t file_offset,
SearchPathList* search_path_list,
+ bool no_map_exec_support_fallback_enabled,
Error* error) {
const char* base_name = GetBaseNamePtr(lib_name);
}
// Load the library
- if (!lib->Load(full_path.c_str(), load_address, file_offset, error))
+ if (!lib->Load(full_path.c_str(), load_address, file_offset,
+ no_map_exec_support_fallback_enabled, error))
return NULL;
// Load all dependendent libraries.
0U /* load address */,
0U /* file offset */,
search_path_list,
+ no_map_exec_support_fallback_enabled,
&dep_error);
if (!dependency) {
error->Format("When loading %s: %s", base_name, dep_error.c_str());
#error "Unsupported target abi"
#endif
-const size_t kMaxFilenameInZip = 256;
-const size_t kPageSize = 4096;
-
-LibraryView* LibraryList::LoadLibraryInZipFile(const char* zip_file_path,
- const char* lib_name,
- int dlopen_flags,
- uintptr_t load_address,
- SearchPathList* search_path_list,
- Error* error) {
- String fullname;
- fullname.Reserve(kMaxFilenameInZip);
- fullname = "lib/";
- fullname += CURRENT_ABI;
- fullname += "/crazy.";
- fullname += lib_name;
-
- if (fullname.size() + 1 > kMaxFilenameInZip) {
+String LibraryList::GetLibraryFilePathInZipFile(const char* lib_name) {
+ String path;
+ path.Reserve(kMaxFilePathLengthInZip);
+ path = "lib/";
+ path += CURRENT_ABI;
+ path += "/crazy.";
+ path += lib_name;
+ return path;
+}
+
+int LibraryList::FindMappableLibraryInZipFile(
+ const char* zip_file_path,
+ const char* lib_name,
+ Error* error) {
+ String path = GetLibraryFilePathInZipFile(lib_name);
+ if (path.size() >= kMaxFilePathLengthInZip) {
error->Format("Filename too long for a file in a zip file %s\n",
- fullname.c_str());
- return NULL;
+ path.c_str());
+ return CRAZY_OFFSET_FAILED;
}
- int offset = FindStartOffsetOfFileInZipFile(zip_file_path, fullname.c_str());
- if (offset == -1) {
- return NULL;
+ int offset = FindStartOffsetOfFileInZipFile(zip_file_path, path.c_str());
+ if (offset == CRAZY_OFFSET_FAILED) {
+ return CRAZY_OFFSET_FAILED;
}
- if ((offset & (kPageSize - 1)) != 0) {
+ static_assert((kZipAlignmentPageSize & (kZipAlignmentPageSize - 1)) == 0,
+ "kZipAlignmentPageSize must be a power of 2");
+ if ((offset & (kZipAlignmentPageSize - 1)) != 0) {
error->Format("Library %s is not page aligned in zipfile %s\n",
lib_name, zip_file_path);
+ return CRAZY_OFFSET_FAILED;
+ }
+
+ assert(offset != CRAZY_OFFSET_FAILED);
+ return offset;
+}
+
+LibraryView* LibraryList::LoadLibraryInZipFile(
+ const char* zip_file_path,
+ const char* lib_name,
+ int dlopen_flags,
+ uintptr_t load_address,
+ SearchPathList* search_path_list,
+ bool no_map_exec_support_fallback_enabled,
+ Error* error) {
+ int offset = FindMappableLibraryInZipFile(zip_file_path, lib_name, error);
+ if (offset == CRAZY_OFFSET_FAILED) {
return NULL;
}
return LoadLibrary(
zip_file_path, dlopen_flags, load_address, offset,
- search_path_list, error);
+ search_path_list, no_map_exec_support_fallback_enabled, error);
}
void LibraryList::AddLibrary(LibraryView* wrap) {