From 05752398db7f25d7892b62cb39615eee468f1db8 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Tue, 8 Mar 2016 16:50:20 -0800 Subject: [PATCH] Use per character suffix for multi image E.g. if you pull the oat files from the device, you get oat files with the following names: system@framework@boot.art But the name stored in the image header is: boot.art So we need to append system@framework@ as a file name prefix to each image file to get the actual one. Required for adding oatdump support for app images. Bug: 22858531 Bug: 27408512 Change-Id: I93dd3f16652400f232e6175670fcd572395879e0 --- runtime/gc/space/image_space.cc | 63 ++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 41 deletions(-) diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index b3a8e8448..357ba949e 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -1459,50 +1459,31 @@ void ImageSpace::CreateMultiImageLocations(const std::string& input_image_file_n // images[0] is f/c/d/e.art // ---------------------------------------------- // images[1] is g/h/i/j.art -> /a/b/h/i/j.art - - // Derive pattern. - std::vector left; - Split(input_image_file_name, '/', &left); - std::vector right; - Split(images[0], '/', &right); - - size_t common = 1; - while (common < left.size() && common < right.size()) { - if (left[left.size() - common - 1] != right[right.size() - common - 1]) { - break; - } - common++; - } - - std::vector prefix_vector(left.begin(), left.end() - common); - std::string common_prefix = Join(prefix_vector, '/'); - if (!common_prefix.empty() && common_prefix[0] != '/' && input_image_file_name[0] == '/') { - common_prefix = "/" + common_prefix; - } + const std::string& first_image = images[0]; + // Length of common suffix. + size_t common = 0; + while (common < input_image_file_name.size() && + common < first_image.size() && + *(input_image_file_name.end() - common - 1) == *(first_image.end() - common - 1)) { + ++common; + } + // We want to replace the prefix of the input image with the prefix of the boot class path. + // This handles the case where the image file contains @ separators. + // Example image_file_name is oats/system@framework@boot.art + // images[0] is .../arm/boot.art + // means that the image name prefix will be oats/system@framework@ + // so that the other images are openable. + const size_t old_prefix_length = first_image.size() - common; + const std::string new_prefix = input_image_file_name.substr( + 0, + input_image_file_name.size() - common); // Apply pattern to images[1] .. images[n]. for (size_t i = 1; i < images.size(); ++i) { - std::string image = images[i]; - - size_t rslash = std::string::npos; - for (size_t j = 0; j < common; ++j) { - if (rslash != std::string::npos) { - rslash--; - } - - rslash = image.rfind('/', rslash); - if (rslash == std::string::npos) { - rslash = 0; - } - if (rslash == 0) { - break; - } - } - std::string image_part = image.substr(rslash); - - std::string new_image = common_prefix + (StartsWith(image_part, "/") ? "" : "/") + - image_part; - image_file_names->push_back(new_image); + const std::string& image = images[i]; + CHECK_GT(image.length(), old_prefix_length); + std::string suffix = image.substr(old_prefix_length); + image_file_names->push_back(new_prefix + suffix); } } -- 2.11.0