diff options
author | Dmitriy Ivanov <dimitry@google.com> | 2015-10-01 18:41:57 -0700 |
---|---|---|
committer | Dmitriy Ivanov <dimitry@google.com> | 2015-10-07 11:44:53 -0700 |
commit | a1feb117e4d5614548574f28dede3443e073512b (patch) | |
tree | 6078618ff745b802f986119d0534433a8d7df2d1 /linker/linker_utils.cpp | |
parent | 748421beef0ed8625920a27b3753a79c2652b6ef (diff) |
Make dt_runpath work for libraries opened from apk
This patch also fixes realpath for libraries opened directly
from apks.
Bug: http://b/21960914
Bug: http://b/21961857
Change-Id: I35ade661c87f1d448191f385811f6e9fd3cacf11
Diffstat (limited to 'linker/linker_utils.cpp')
-rw-r--r-- | linker/linker_utils.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/linker/linker_utils.cpp b/linker/linker_utils.cpp new file mode 100644 index 000000000..5d39d835f --- /dev/null +++ b/linker/linker_utils.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "linker_utils.h" +#include "linker_debug.h" + +bool normalize_path(const char* path, std::string* normalized_path) { + // Input should be an absolute path + if (path[0] != '/') { + PRINT("canonize_path - invalid input: '%s', the input path should be absolute", path); + return false; + } + + const size_t len = strlen(path) + 1; + char buf[len]; + + const char* in_ptr = path; + char* out_ptr = buf; + + while (*in_ptr != 0) { + if (*in_ptr == '/') { + char c1 = in_ptr[1]; + if (c1 == '.') { + char c2 = in_ptr[2]; + if (c2 == '/') { + in_ptr += 2; + continue; + } else if (c2 == '.' && (in_ptr[3] == '/' || in_ptr[3] == 0)) { + in_ptr += 3; + while (out_ptr > buf && *--out_ptr != '/') { + } + if (in_ptr[0] == 0) { + // retain '/' + out_ptr++; + } + continue; + } + } else if (c1 == '/') { + ++in_ptr; + continue; + } + } + *out_ptr++ = *in_ptr++; + } + + *out_ptr = 0; + *normalized_path = buf; + return true; +} + |