Fix dlopen of main executable by absolute path
This CL adds initialization of inode for the main executable
which enables linker to resolve the correct soinfo when
application calls dlopen with absolute path to the
main executable.
Bug: http://b/28420266
Change-Id: I102e07bde454bd44c6e46075e3faeeb5092830d8
(cherry picked from commit 2ba1cf39ae6087249a839ec7b3793d4d4fa75438)
diff --git a/linker/linker.cpp b/linker/linker.cpp
index d21625e..799ec50 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -4142,6 +4142,20 @@
extern "C" int __system_properties_init(void);
+static const char* get_executable_path() {
+ static std::string executable_path;
+ if (executable_path.empty()) {
+ char path[PATH_MAX];
+ ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
+ if (path_len == -1 || path_len >= static_cast<ssize_t>(sizeof(path))) {
+ __libc_fatal("readlink('/proc/self/exe') failed: %s", strerror(errno));
+ }
+ executable_path = std::string(path, path_len);
+ }
+
+ return executable_path.c_str();
+}
+
/*
* This code is called after the linker has linked itself and
* fixed it's own GOT. It is safe to make references to externs
@@ -4188,7 +4202,13 @@
}
}
- soinfo* si = soinfo_alloc(&g_default_namespace, args.argv[0], nullptr, 0, RTLD_GLOBAL);
+ const char* executable_path = get_executable_path();
+ struct stat file_stat;
+ if (TEMP_FAILURE_RETRY(stat(executable_path, &file_stat)) != 0) {
+ __libc_fatal("unable to stat file for the executable \"%s\": %s", executable_path, strerror(errno));
+ }
+
+ soinfo* si = soinfo_alloc(&g_default_namespace, executable_path, &file_stat, 0, RTLD_GLOBAL);
if (si == nullptr) {
__libc_fatal("Couldn't allocate soinfo: out of memory?");
}
@@ -4201,7 +4221,7 @@
// gdb aware of them before loading the rest of the dependency
// tree.
map->l_addr = 0;
- map->l_name = args.argv[0];
+ map->l_name = const_cast<char*>(executable_path);
insert_link_map_into_debug_map(map);
init_linker_info_for_gdb(linker_base);