aboutsummaryrefslogtreecommitdiff
path: root/linker/linker_utils.cpp
diff options
context:
space:
mode:
authorDimitry Ivanov <dimitry@google.com>2016-08-04 11:50:36 -0700
committerDimitry Ivanov <dimitry@google.com>2016-08-08 16:12:53 -0700
commit48ec288d40d272e6fe5e68c4c0a9778b55e24f8a (patch)
tree4070843ac34ee5924221c2885b9ed6a26d03a5dd /linker/linker_utils.cpp
parentb943f303a2d67d1e4c2fc8c4df3b4407888d777b (diff)
downloadbionic-48ec288d40d272e6fe5e68c4c0a9778b55e24f8a.tar.gz
Extract soinfo and globals to separate files.
Move soinfo and globals out of linker.cpp to separate files. Breaking up huge linker.cpp into smaller peaces in order to make it easier to extract part of the code that belongs to libdl.so and remove parts of the code that do not belong to linker (refactoring part 2 of many) Change-Id: I868417f4b8d2b84d0e8265e354bc7977161497e2
Diffstat (limited to 'linker/linker_utils.cpp')
-rw-r--r--linker/linker_utils.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/linker/linker_utils.cpp b/linker/linker_utils.cpp
index fb070eed0..e7447e402 100644
--- a/linker/linker_utils.cpp
+++ b/linker/linker_utils.cpp
@@ -15,7 +15,26 @@
*/
#include "linker_utils.h"
+
#include "linker_debug.h"
+#include "linker_globals.h"
+
+#include "android-base/strings.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+std::string dirname(const char* path) {
+ const char* last_slash = strrchr(path, '/');
+
+ if (last_slash == path) {
+ return "/";
+ } else if (last_slash == nullptr) {
+ return ".";
+ } else {
+ return std::string(path, last_slash - path);
+ }
+}
bool normalize_path(const char* path, std::string* normalized_path) {
// Input should be an absolute path
@@ -134,3 +153,52 @@ size_t page_offset(off64_t offset) {
return static_cast<size_t>(offset & (PAGE_SIZE-1));
}
+void split_path(const char* path, const char* delimiters,
+ std::vector<std::string>* paths) {
+ if (path != nullptr && path[0] != 0) {
+ *paths = android::base::Split(path, delimiters);
+ }
+}
+
+void resolve_paths(std::vector<std::string>& paths,
+ std::vector<std::string>* resolved_paths) {
+ resolved_paths->clear();
+ for (const auto& path : paths) {
+ char resolved_path[PATH_MAX];
+ const char* original_path = path.c_str();
+ if (realpath(original_path, resolved_path) != nullptr) {
+ struct stat s;
+ if (stat(resolved_path, &s) == 0) {
+ if (S_ISDIR(s.st_mode)) {
+ resolved_paths->push_back(resolved_path);
+ } else {
+ DL_WARN("Warning: \"%s\" is not a directory (excluding from path)", resolved_path);
+ continue;
+ }
+ } else {
+ DL_WARN("Warning: cannot stat file \"%s\": %s", resolved_path, strerror(errno));
+ continue;
+ }
+ } else {
+ std::string zip_path;
+ std::string entry_path;
+
+ std::string normalized_path;
+
+ if (!normalize_path(original_path, &normalized_path)) {
+ DL_WARN("Warning: unable to normalize \"%s\"", original_path);
+ continue;
+ }
+
+ if (parse_zip_path(normalized_path.c_str(), &zip_path, &entry_path)) {
+ if (realpath(zip_path.c_str(), resolved_path) == nullptr) {
+ DL_WARN("Warning: unable to resolve \"%s\": %s", zip_path.c_str(), strerror(errno));
+ continue;
+ }
+
+ resolved_paths->push_back(std::string(resolved_path) + kZipFileSeparator + entry_path);
+ }
+ }
+ }
+}
+