Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "dex_file.h"
     18 
     19 #include <sys/mman.h>
     20 
     21 #include <memory>
     22 
     23 #include "base/stl_util.h"
     24 #include "base/unix_file/fd_file.h"
     25 #include "common_runtime_test.h"
     26 #include "dex_file-inl.h"
     27 #include "mem_map.h"
     28 #include "os.h"
     29 #include "scoped_thread_state_change-inl.h"
     30 #include "thread-current-inl.h"
     31 #include "utils.h"
     32 
     33 namespace art {
     34 
     35 class DexFileTest : public CommonRuntimeTest {};
     36 
     37 TEST_F(DexFileTest, Open) {
     38   ScopedObjectAccess soa(Thread::Current());
     39   std::unique_ptr<const DexFile> dex(OpenTestDexFile("Nested"));
     40   ASSERT_TRUE(dex.get() != nullptr);
     41 }
     42 
     43 static inline std::vector<uint8_t> DecodeBase64Vec(const char* src) {
     44   std::vector<uint8_t> res;
     45   size_t size;
     46   std::unique_ptr<uint8_t[]> data(DecodeBase64(src, &size));
     47   res.resize(size);
     48   memcpy(res.data(), data.get(), size);
     49   return res;
     50 }
     51 
     52 // Although this is the same content logically as the Nested test dex,
     53 // the DexFileHeader test is sensitive to subtle changes in the
     54 // contents due to the checksum etc, so we embed the exact input here.
     55 //
     56 // class Nested {
     57 //     class Inner {
     58 //     }
     59 // }
     60 static const char kRawDex[] =
     61   "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
     62   "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
     63   "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
     64   "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
     65   "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
     66   "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
     67   "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
     68   "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
     69   "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
     70   "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
     71   "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
     72   "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
     73   "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
     74   "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
     75   "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
     76   "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
     77 
     78 // kRawDex38 and 39 are dex'ed versions of the following Java source :
     79 //
     80 // public class Main {
     81 //     public static void main(String[] foo) {
     82 //     }
     83 // }
     84 //
     85 // The dex file was manually edited to change its dex version code to 38
     86 // or 39, respectively.
     87 static const char kRawDex38[] =
     88   "ZGV4CjAzOAC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
     89   "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
     90   "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
     91   "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
     92   "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
     93   "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
     94   "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
     95   "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
     96   "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
     97   "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
     98 
     99 static const char kRawDex39[] =
    100   "ZGV4CjAzOQC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
    101   "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
    102   "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
    103   "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
    104   "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
    105   "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
    106   "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
    107   "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
    108   "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
    109   "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
    110 
    111 static const char kRawDexZeroLength[] =
    112   "UEsDBAoAAAAAAOhxAkkAAAAAAAAAAAAAAAALABwAY2xhc3Nlcy5kZXhVVAkAA2QNoVdnDaFXdXgL"
    113   "AAEE5AMBAASIEwAAUEsBAh4DCgAAAAAA6HECSQAAAAAAAAAAAAAAAAsAGAAAAAAAAAAAAKCBAAAA"
    114   "AGNsYXNzZXMuZGV4VVQFAANkDaFXdXgLAAEE5AMBAASIEwAAUEsFBgAAAAABAAEAUQAAAEUAAAAA"
    115   "AA==";
    116 
    117 static const char kRawZipClassesDexPresent[] =
    118   "UEsDBBQAAAAIANVRN0ms99lIMQEAACACAAALABwAY2xhc3Nlcy5kZXhVVAkAAwFj5VcUY+VXdXgL"
    119   "AAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQCEwNDAQMDQ0WY"
    120   "iRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGxGxAHAnEIEEcA"
    121   "cS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8UFGgP6Fu4IOa"
    122   "wczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYxMIX5MAhHIykL"
    123   "LinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHCmg0pvBkVIGpA"
    124   "Yc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACADVUTdJrPfZSDEBAAAg"
    125   "AgAACwAYAAAAAAAAAAAAoIEAAAAAY2xhc3Nlcy5kZXhVVAUAAwFj5Vd1eAsAAQTkAwEABIgTAABQ"
    126   "SwUGAAAAAAEAAQBRAAAAdgEAAAAA";
    127 
    128 static const char kRawZipClassesDexAbsent[] =
    129   "UEsDBBQAAAAIANVRN0ms99lIMQEAACACAAAOABwAbm90Y2xhc3Nlcy5kZXhVVAkAAwFj5VcUY+VX"
    130   "dXgLAAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQCEwNDAQMD"
    131   "Q0WYiRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGxGxAHAnEI"
    132   "EEcAcS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8UFGgP6Fu"
    133   "4IOawczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYxMIX5MAhH"
    134   "IykLLinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHCmg0pvBkV"
    135   "IGpAYc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACADVUTdJrPfZSDEB"
    136   "AAAgAgAADgAYAAAAAAAAAAAAoIEAAAAAbm90Y2xhc3Nlcy5kZXhVVAUAAwFj5Vd1eAsAAQTkAwEA"
    137   "BIgTAABQSwUGAAAAAAEAAQBUAAAAeQEAAAAA";
    138 
    139 static const char kRawZipThreeDexFiles[] =
    140   "UEsDBBQAAAAIAP1WN0ms99lIMQEAACACAAAMABwAY2xhc3NlczIuZGV4VVQJAAOtbOVXrWzlV3V4"
    141   "CwABBOQDAQAEiBMAAEtJreAyMLZg2GHVfXLK3JLPN5acWTdrw/H/9adW3ll972m0AhMDQwEDA0NF"
    142   "mIkQAxT0MDIwcDBAxFmAeAIQA5UxLGBAAGYg3gHEQKUMF4DYAMj4AKSVgLQWEBsBsRsQBwJxCBBH"
    143   "AHEuI0Q9E9RcNijNBDWTFcqWYUSyCKiDHWoPQgTBZ4bSdYwwOUawXDEjxOwCAZCJfFBRoD+hbuCD"
    144   "msHMwGaTmZdZYsfA5uObmJlnzSDkk5VYlqifk5iXru+flJWaXGLNwAmS0gOJMzCGMTCF+TAIRyMp"
    145   "Cy4pysxLt2ZgyQUqAzmYj4EZTIL909jA8oGRkbODiQfJ/TAaFs6wMJkA9RMsvFmRwpoNKbwZFSBq"
    146   "QGHOKAARB4UbkwLETFA8MEPVgMKCQQGiBhxOUPWgeAYAUEsDBBQAAAAIAABXN0ms99lIMQEAACAC"
    147   "AAAMABwAY2xhc3NlczMuZGV4VVQJAAOvbOVXr2zlV3V4CwABBOQDAQAEiBMAAEtJreAyMLZg2GHV"
    148   "fXLK3JLPN5acWTdrw/H/9adW3ll972m0AhMDQwEDA0NFmIkQAxT0MDIwcDBAxFmAeAIQA5UxLGBA"
    149   "AGYg3gHEQKUMF4DYAMj4AKSVgLQWEBsBsRsQBwJxCBBHAHEuI0Q9E9RcNijNBDWTFcqWYUSyCKiD"
    150   "HWoPQgTBZ4bSdYwwOUawXDEjxOwCAZCJfFBRoD+hbuCDmsHMwGaTmZdZYsfA5uObmJlnzSDkk5VY"
    151   "lqifk5iXru+flJWaXGLNwAmS0gOJMzCGMTCF+TAIRyMpCy4pysxLt2ZgyQUqAzmYj4EZTIL909jA"
    152   "8oGRkbODiQfJ/TAaFs6wMJkA9RMsvFmRwpoNKbwZFSBqQGHOKAARB4UbkwLETFA8MEPVgMKCQQGi"
    153   "BhxOUPWgeAYAUEsDBBQAAAAIANVRN0ms99lIMQEAACACAAALABwAY2xhc3Nlcy5kZXhVVAkAAwFj"
    154   "5VetbOVXdXgLAAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQC"
    155   "EwNDAQMDQ0WYiRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGx"
    156   "GxAHAnEIEEcAcS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8"
    157   "UFGgP6Fu4IOawczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYx"
    158   "MIX5MAhHIykLLinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHC"
    159   "mg0pvBkVIGpAYc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACAD9VjdJ"
    160   "rPfZSDEBAAAgAgAADAAYAAAAAAAAAAAAoIEAAAAAY2xhc3NlczIuZGV4VVQFAAOtbOVXdXgLAAEE"
    161   "5AMBAASIEwAAUEsBAh4DFAAAAAgAAFc3Saz32UgxAQAAIAIAAAwAGAAAAAAAAAAAAKCBdwEAAGNs"
    162   "YXNzZXMzLmRleFVUBQADr2zlV3V4CwABBOQDAQAEiBMAAFBLAQIeAxQAAAAIANVRN0ms99lIMQEA"
    163   "ACACAAALABgAAAAAAAAAAACgge4CAABjbGFzc2VzLmRleFVUBQADAWPlV3V4CwABBOQDAQAEiBMA"
    164   "AFBLBQYAAAAAAwADAPUAAABkBAAAAAA=";
    165 
    166 static const char kRawDexBadMapOffset[] =
    167   "ZGV4CjAzNQAZKGSz85r+tXJ1I24FYi+FpQtWbXtelAmoAQAAcAAAAHhWNBIAAAAAAAAAAEAwIBAF"
    168   "AAAAcAAAAAMAAACEAAAAAQAAAJAAAAAAAAAAAAAAAAIAAACcAAAAAQAAAKwAAADcAAAAzAAAAOQA"
    169   "AADsAAAA9AAAAPkAAAANAQAAAgAAAAMAAAAEAAAABAAAAAIAAAAAAAAAAAAAAAAAAAABAAAAAAAA"
    170   "AAAAAAABAAAAAQAAAAAAAAABAAAAAAAAABUBAAAAAAAAAQABAAEAAAAQAQAABAAAAHAQAQAAAA4A"
    171   "Bjxpbml0PgAGQS5qYXZhAANMQTsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgABAAcOAAAAAQAAgYAE"
    172   "zAEACwAAAAAAAAABAAAAAAAAAAEAAAAFAAAAcAAAAAIAAAADAAAAhAAAAAMAAAABAAAAkAAAAAUA"
    173   "AAACAAAAnAAAAAYAAAABAAAArAAAAAEgAAABAAAAzAAAAAIgAAAFAAAA5AAAAAMgAAABAAAAEAEA"
    174   "AAAgAAABAAAAFQEAAAAQAAABAAAAIAEAAA==";
    175 
    176 static const char kRawDexDebugInfoLocalNullType[] =
    177     "ZGV4CjAzNQA+Kwj2g6OZMH88OvK9Ey6ycdIsFCt18ED8AQAAcAAAAHhWNBIAAAAAAAAAAHQBAAAI"
    178     "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAMAQAA8AAAABwB"
    179     "AAAkAQAALAEAAC8BAAA0AQAASAEAAEsBAABOAQAAAgAAAAMAAAAEAAAABQAAAAIAAAAAAAAAAAAA"
    180     "AAUAAAADAAAAAAAAAAEAAQAAAAAAAQAAAAYAAAACAAEAAAAAAAEAAAABAAAAAgAAAAAAAAABAAAA"
    181     "AAAAAGMBAAAAAAAAAQABAAEAAABUAQAABAAAAHAQAgAAAA4AAgABAAAAAABZAQAAAgAAABIQDwAG"
    182     "PGluaXQ+AAZBLmphdmEAAUkAA0xBOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAFhAAR0aGlzAAEA"
    183     "Bw4AAwAHDh4DAAcAAAAAAQEAgYAE8AEBAIgCAAAACwAAAAAAAAABAAAAAAAAAAEAAAAIAAAAcAAA"
    184     "AAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAAuAAAAAYAAAABAAAA0AAAAAEgAAACAAAA"
    185     "8AAAAAIgAAAIAAAAHAEAAAMgAAACAAAAVAEAAAAgAAABAAAAYwEAAAAQAAABAAAAdAEAAA==";
    186 
    187 static void DecodeAndWriteDexFile(const char* base64, const char* location) {
    188   // decode base64
    189   CHECK(base64 != nullptr);
    190   std::vector<uint8_t> dex_bytes = DecodeBase64Vec(base64);
    191   CHECK_NE(dex_bytes.size(), 0u);
    192 
    193   // write to provided file
    194   std::unique_ptr<File> file(OS::CreateEmptyFile(location));
    195   CHECK(file.get() != nullptr);
    196   if (!file->WriteFully(dex_bytes.data(), dex_bytes.size())) {
    197     PLOG(FATAL) << "Failed to write base64 as dex file";
    198   }
    199   if (file->FlushCloseOrErase() != 0) {
    200     PLOG(FATAL) << "Could not flush and close test file.";
    201   }
    202 }
    203 
    204 static bool OpenDexFilesBase64(const char* base64,
    205                                const char* location,
    206                                std::vector<std::unique_ptr<const DexFile>>* dex_files,
    207                                std::string* error_msg) {
    208   DecodeAndWriteDexFile(base64, location);
    209 
    210   // read dex file(s)
    211   ScopedObjectAccess soa(Thread::Current());
    212   static constexpr bool kVerifyChecksum = true;
    213   std::vector<std::unique_ptr<const DexFile>> tmp;
    214   bool success = DexFile::Open(location, location, kVerifyChecksum, error_msg, &tmp);
    215   if (success) {
    216     for (std::unique_ptr<const DexFile>& dex_file : tmp) {
    217       EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
    218       EXPECT_TRUE(dex_file->IsReadOnly());
    219     }
    220     *dex_files = std::move(tmp);
    221   }
    222   return success;
    223 }
    224 
    225 static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
    226                                                         const char* location) {
    227   // read dex files.
    228   std::string error_msg;
    229   std::vector<std::unique_ptr<const DexFile>> dex_files;
    230   bool success = OpenDexFilesBase64(base64, location, &dex_files, &error_msg);
    231   CHECK(success) << error_msg;
    232   EXPECT_EQ(1U, dex_files.size());
    233   return std::move(dex_files[0]);
    234 }
    235 
    236 static std::unique_ptr<const DexFile> OpenDexFileInMemoryBase64(const char* base64,
    237                                                                 const char* location,
    238                                                                 uint32_t location_checksum,
    239                                                                 bool expect_success) {
    240   CHECK(base64 != nullptr);
    241   std::vector<uint8_t> dex_bytes = DecodeBase64Vec(base64);
    242   CHECK_NE(dex_bytes.size(), 0u);
    243 
    244   std::string error_message;
    245   std::unique_ptr<MemMap> region(MemMap::MapAnonymous("test-region",
    246                                                       nullptr,
    247                                                       dex_bytes.size(),
    248                                                       PROT_READ | PROT_WRITE,
    249                                                       /* low_4gb */ false,
    250                                                       /* reuse */ false,
    251                                                       &error_message));
    252   memcpy(region->Begin(), dex_bytes.data(), dex_bytes.size());
    253   std::unique_ptr<const DexFile> dex_file(DexFile::Open(location,
    254                                                         location_checksum,
    255                                                         std::move(region),
    256                                                         /* verify */ true,
    257                                                         /* verify_checksum */ true,
    258                                                         &error_message));
    259   if (expect_success) {
    260     CHECK(dex_file != nullptr) << error_message;
    261   } else {
    262     CHECK(dex_file == nullptr) << "Expected dex file open to fail.";
    263   }
    264   return dex_file;
    265 }
    266 
    267 static void ValidateDexFileHeader(std::unique_ptr<const DexFile> dex_file) {
    268   static const uint8_t kExpectedDexFileMagic[8] = {
    269     /* d */ 0x64, /* e */ 0x64, /* x */ 0x78, /* \n */ 0x0d,
    270     /* 0 */ 0x30, /* 3 */ 0x33, /* 5 */ 0x35, /* \0 */ 0x00
    271   };
    272   static const uint8_t kExpectedSha1[DexFile::kSha1DigestSize] = {
    273     0x7b, 0xb8, 0x0c, 0xd4, 0x1f, 0xd6, 0x1e, 0xc5,
    274     0x89, 0xe8, 0xbe, 0xe5, 0x18, 0x02, 0x12, 0x18,
    275     0x2e, 0xf2, 0x8c, 0x3d,
    276   };
    277 
    278   const DexFile::Header& header = dex_file->GetHeader();
    279   EXPECT_EQ(*kExpectedDexFileMagic, *header.magic_);
    280   EXPECT_EQ(0x00d87910U, header.checksum_);
    281   EXPECT_EQ(*kExpectedSha1, *header.signature_);
    282   EXPECT_EQ(904U, header.file_size_);
    283   EXPECT_EQ(112U, header.header_size_);
    284   EXPECT_EQ(0U, header.link_size_);
    285   EXPECT_EQ(0U, header.link_off_);
    286   EXPECT_EQ(15U, header.string_ids_size_);
    287   EXPECT_EQ(112U, header.string_ids_off_);
    288   EXPECT_EQ(7U, header.type_ids_size_);
    289   EXPECT_EQ(172U, header.type_ids_off_);
    290   EXPECT_EQ(2U, header.proto_ids_size_);
    291   EXPECT_EQ(200U, header.proto_ids_off_);
    292   EXPECT_EQ(1U, header.field_ids_size_);
    293   EXPECT_EQ(224U, header.field_ids_off_);
    294   EXPECT_EQ(3U, header.method_ids_size_);
    295   EXPECT_EQ(232U, header.method_ids_off_);
    296   EXPECT_EQ(2U, header.class_defs_size_);
    297   EXPECT_EQ(256U, header.class_defs_off_);
    298   EXPECT_EQ(584U, header.data_size_);
    299   EXPECT_EQ(320U, header.data_off_);
    300 
    301   EXPECT_EQ(header.checksum_, dex_file->GetLocationChecksum());
    302 }
    303 
    304 TEST_F(DexFileTest, Header) {
    305   ScratchFile tmp;
    306   std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
    307   ValidateDexFileHeader(std::move(raw));
    308 }
    309 
    310 TEST_F(DexFileTest, HeaderInMemory) {
    311   ScratchFile tmp;
    312   std::unique_ptr<const DexFile> raw =
    313       OpenDexFileInMemoryBase64(kRawDex, tmp.GetFilename().c_str(), 0x00d87910U, true);
    314   ValidateDexFileHeader(std::move(raw));
    315 }
    316 
    317 TEST_F(DexFileTest, Version38Accepted) {
    318   ScratchFile tmp;
    319   std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex38, tmp.GetFilename().c_str()));
    320   ASSERT_TRUE(raw.get() != nullptr);
    321 
    322   const DexFile::Header& header = raw->GetHeader();
    323   EXPECT_EQ(38u, header.GetVersion());
    324 }
    325 
    326 TEST_F(DexFileTest, Version39Rejected) {
    327   ScratchFile tmp;
    328   const char* location = tmp.GetFilename().c_str();
    329   DecodeAndWriteDexFile(kRawDex39, location);
    330 
    331   ScopedObjectAccess soa(Thread::Current());
    332   static constexpr bool kVerifyChecksum = true;
    333   std::string error_msg;
    334   std::vector<std::unique_ptr<const DexFile>> dex_files;
    335   ASSERT_FALSE(DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files));
    336 }
    337 
    338 TEST_F(DexFileTest, ZeroLengthDexRejected) {
    339   ScratchFile tmp;
    340   const char* location = tmp.GetFilename().c_str();
    341   DecodeAndWriteDexFile(kRawDexZeroLength, location);
    342 
    343   ScopedObjectAccess soa(Thread::Current());
    344   static constexpr bool kVerifyChecksum = true;
    345   std::string error_msg;
    346   std::vector<std::unique_ptr<const DexFile>> dex_files;
    347   ASSERT_FALSE(DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files));
    348 }
    349 
    350 TEST_F(DexFileTest, GetLocationChecksum) {
    351   ScopedObjectAccess soa(Thread::Current());
    352   std::unique_ptr<const DexFile> raw(OpenTestDexFile("Main"));
    353   EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
    354 }
    355 
    356 TEST_F(DexFileTest, GetChecksum) {
    357   std::vector<uint32_t> checksums;
    358   ScopedObjectAccess soa(Thread::Current());
    359   std::string error_msg;
    360   EXPECT_TRUE(DexFile::GetMultiDexChecksums(GetLibCoreDexFileNames()[0].c_str(), &checksums, &error_msg))
    361       << error_msg;
    362   ASSERT_EQ(1U, checksums.size());
    363   EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksums[0]);
    364 }
    365 
    366 TEST_F(DexFileTest, GetMultiDexChecksums) {
    367   std::string error_msg;
    368   std::vector<uint32_t> checksums;
    369   std::string multidex_file = GetTestDexFileName("MultiDex");
    370   EXPECT_TRUE(DexFile::GetMultiDexChecksums(multidex_file.c_str(),
    371                                             &checksums,
    372                                             &error_msg)) << error_msg;
    373 
    374   std::vector<std::unique_ptr<const DexFile>> dexes = OpenTestDexFiles("MultiDex");
    375   ASSERT_EQ(2U, dexes.size());
    376   ASSERT_EQ(2U, checksums.size());
    377 
    378   EXPECT_EQ(dexes[0]->GetLocation(), DexFile::GetMultiDexLocation(0, multidex_file.c_str()));
    379   EXPECT_EQ(dexes[0]->GetLocationChecksum(), checksums[0]);
    380 
    381   EXPECT_EQ(dexes[1]->GetLocation(), DexFile::GetMultiDexLocation(1, multidex_file.c_str()));
    382   EXPECT_EQ(dexes[1]->GetLocationChecksum(), checksums[1]);
    383 }
    384 
    385 TEST_F(DexFileTest, ClassDefs) {
    386   ScopedObjectAccess soa(Thread::Current());
    387   std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested"));
    388   ASSERT_TRUE(raw.get() != nullptr);
    389   EXPECT_EQ(3U, raw->NumClassDefs());
    390 
    391   const DexFile::ClassDef& c0 = raw->GetClassDef(0);
    392   EXPECT_STREQ("LNested$1;", raw->GetClassDescriptor(c0));
    393 
    394   const DexFile::ClassDef& c1 = raw->GetClassDef(1);
    395   EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c1));
    396 
    397   const DexFile::ClassDef& c2 = raw->GetClassDef(2);
    398   EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c2));
    399 }
    400 
    401 TEST_F(DexFileTest, GetMethodSignature) {
    402   ScopedObjectAccess soa(Thread::Current());
    403   std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
    404   ASSERT_TRUE(raw.get() != nullptr);
    405   EXPECT_EQ(1U, raw->NumClassDefs());
    406 
    407   const DexFile::ClassDef& class_def = raw->GetClassDef(0);
    408   ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
    409 
    410   const uint8_t* class_data = raw->GetClassData(class_def);
    411   ASSERT_TRUE(class_data != nullptr);
    412   ClassDataItemIterator it(*raw, class_data);
    413 
    414   EXPECT_EQ(1u, it.NumDirectMethods());
    415 
    416   // Check the signature for the static initializer.
    417   {
    418     ASSERT_EQ(1U, it.NumDirectMethods());
    419     const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
    420     const char* name = raw->StringDataByIdx(method_id.name_idx_);
    421     ASSERT_STREQ("<init>", name);
    422     std::string signature(raw->GetMethodSignature(method_id).ToString());
    423     ASSERT_EQ("()V", signature);
    424   }
    425 
    426   // Check both virtual methods.
    427   ASSERT_EQ(2U, it.NumVirtualMethods());
    428   {
    429     it.Next();
    430     const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
    431 
    432     const char* name = raw->StringDataByIdx(method_id.name_idx_);
    433     ASSERT_STREQ("m1", name);
    434 
    435     std::string signature(raw->GetMethodSignature(method_id).ToString());
    436     ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
    437   }
    438 
    439   {
    440     it.Next();
    441     const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
    442 
    443     const char* name = raw->StringDataByIdx(method_id.name_idx_);
    444     ASSERT_STREQ("m2", name);
    445 
    446     std::string signature(raw->GetMethodSignature(method_id).ToString());
    447     ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
    448   }
    449 }
    450 
    451 TEST_F(DexFileTest, FindStringId) {
    452   ScopedObjectAccess soa(Thread::Current());
    453   std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
    454   ASSERT_TRUE(raw.get() != nullptr);
    455   EXPECT_EQ(1U, raw->NumClassDefs());
    456 
    457   const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
    458       "D", "I", "J", nullptr };
    459   for (size_t i = 0; strings[i] != nullptr; i++) {
    460     const char* str = strings[i];
    461     const DexFile::StringId* str_id = raw->FindStringId(str);
    462     const char* dex_str = raw->GetStringData(*str_id);
    463     EXPECT_STREQ(dex_str, str);
    464   }
    465 }
    466 
    467 TEST_F(DexFileTest, FindTypeId) {
    468   for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
    469     const char* type_str = java_lang_dex_file_->StringByTypeIdx(dex::TypeIndex(i));
    470     const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
    471     ASSERT_TRUE(type_str_id != nullptr);
    472     dex::StringIndex type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
    473     const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
    474     ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str));
    475     ASSERT_TRUE(type_id != nullptr);
    476     EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id).index_, i);
    477   }
    478 }
    479 
    480 TEST_F(DexFileTest, FindProtoId) {
    481   for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
    482     const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
    483     const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
    484     std::vector<dex::TypeIndex> to_find_types;
    485     if (to_find_tl != nullptr) {
    486       for (size_t j = 0; j < to_find_tl->Size(); j++) {
    487         to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
    488       }
    489     }
    490     const DexFile::ProtoId* found =
    491         java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
    492     ASSERT_TRUE(found != nullptr);
    493     EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
    494   }
    495 }
    496 
    497 TEST_F(DexFileTest, FindMethodId) {
    498   for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
    499     const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
    500     const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
    501     const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
    502     const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
    503     const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
    504     ASSERT_TRUE(found != nullptr) << "Didn't find method " << i << ": "
    505         << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
    506         << java_lang_dex_file_->GetStringData(name)
    507         << java_lang_dex_file_->GetMethodSignature(to_find);
    508     EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
    509   }
    510 }
    511 
    512 TEST_F(DexFileTest, FindFieldId) {
    513   for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
    514     const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
    515     const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
    516     const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
    517     const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
    518     const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
    519     ASSERT_TRUE(found != nullptr) << "Didn't find field " << i << ": "
    520         << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
    521         << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
    522         << java_lang_dex_file_->GetStringData(name);
    523     EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
    524   }
    525 }
    526 
    527 TEST_F(DexFileTest, GetMultiDexClassesDexName) {
    528   ASSERT_EQ("classes.dex", DexFile::GetMultiDexClassesDexName(0));
    529   ASSERT_EQ("classes2.dex", DexFile::GetMultiDexClassesDexName(1));
    530   ASSERT_EQ("classes3.dex", DexFile::GetMultiDexClassesDexName(2));
    531   ASSERT_EQ("classes100.dex", DexFile::GetMultiDexClassesDexName(99));
    532 }
    533 
    534 TEST_F(DexFileTest, GetMultiDexLocation) {
    535   std::string dex_location_str = "/system/app/framework.jar";
    536   const char* dex_location = dex_location_str.c_str();
    537   ASSERT_EQ("/system/app/framework.jar", DexFile::GetMultiDexLocation(0, dex_location));
    538   ASSERT_EQ("/system/app/framework.jar!classes2.dex",
    539             DexFile::GetMultiDexLocation(1, dex_location));
    540   ASSERT_EQ("/system/app/framework.jar!classes101.dex",
    541             DexFile::GetMultiDexLocation(100, dex_location));
    542 }
    543 
    544 TEST_F(DexFileTest, GetDexCanonicalLocation) {
    545   ScratchFile file;
    546   UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr));
    547   std::string dex_location(dex_location_real.get());
    548 
    549   ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location.c_str()));
    550   std::string multidex_location = DexFile::GetMultiDexLocation(1, dex_location.c_str());
    551   ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location.c_str()));
    552 
    553   std::string dex_location_sym = dex_location + "symlink";
    554   ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
    555 
    556   ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location_sym.c_str()));
    557 
    558   std::string multidex_location_sym = DexFile::GetMultiDexLocation(1, dex_location_sym.c_str());
    559   ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location_sym.c_str()));
    560 
    561   ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
    562 }
    563 
    564 TEST(DexFileUtilsTest, GetBaseLocationAndMultiDexSuffix) {
    565   EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar"));
    566   EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar!classes2.dex"));
    567   EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar!classes8.dex"));
    568   EXPECT_EQ("", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar"));
    569   EXPECT_EQ("!classes2.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar!classes2.dex"));
    570   EXPECT_EQ("!classes8.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar!classes8.dex"));
    571 }
    572 
    573 TEST_F(DexFileTest, ZipOpenClassesPresent) {
    574   ScratchFile tmp;
    575   std::vector<std::unique_ptr<const DexFile>> dex_files;
    576   std::string error_msg;
    577   ASSERT_TRUE(OpenDexFilesBase64(kRawZipClassesDexPresent, tmp.GetFilename().c_str(), &dex_files,
    578                                  &error_msg));
    579   EXPECT_EQ(dex_files.size(), 1u);
    580 }
    581 
    582 TEST_F(DexFileTest, ZipOpenClassesAbsent) {
    583   ScratchFile tmp;
    584   std::vector<std::unique_ptr<const DexFile>> dex_files;
    585   std::string error_msg;
    586   ASSERT_FALSE(OpenDexFilesBase64(kRawZipClassesDexAbsent, tmp.GetFilename().c_str(), &dex_files,
    587                                   &error_msg));
    588   EXPECT_EQ(dex_files.size(), 0u);
    589 }
    590 
    591 TEST_F(DexFileTest, ZipOpenThreeDexFiles) {
    592   ScratchFile tmp;
    593   std::vector<std::unique_ptr<const DexFile>> dex_files;
    594   std::string error_msg;
    595   ASSERT_TRUE(OpenDexFilesBase64(kRawZipThreeDexFiles, tmp.GetFilename().c_str(), &dex_files,
    596                                  &error_msg));
    597   EXPECT_EQ(dex_files.size(), 3u);
    598 }
    599 
    600 TEST_F(DexFileTest, OpenDexBadMapOffset) {
    601   ScratchFile tmp;
    602   std::unique_ptr<const DexFile> raw =
    603       OpenDexFileInMemoryBase64(kRawDexBadMapOffset, tmp.GetFilename().c_str(), 0xb3642819U, false);
    604   EXPECT_EQ(raw, nullptr);
    605 }
    606 
    607 TEST_F(DexFileTest, GetStringWithNoIndex) {
    608   ScratchFile tmp;
    609   std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
    610   dex::TypeIndex idx;
    611   EXPECT_EQ(raw->StringByTypeIdx(idx), nullptr);
    612 }
    613 
    614 static void Callback(void* context ATTRIBUTE_UNUSED,
    615                      const DexFile::LocalInfo& entry ATTRIBUTE_UNUSED) {
    616 }
    617 
    618 TEST_F(DexFileTest, OpenDexDebugInfoLocalNullType) {
    619   ScratchFile tmp;
    620   std::unique_ptr<const DexFile> raw = OpenDexFileInMemoryBase64(
    621       kRawDexDebugInfoLocalNullType, tmp.GetFilename().c_str(), 0xf25f2b38U, true);
    622   const DexFile::ClassDef& class_def = raw->GetClassDef(0);
    623   const DexFile::CodeItem* code_item = raw->GetCodeItem(raw->FindCodeItemOffset(class_def, 1));
    624   ASSERT_TRUE(raw->DecodeDebugLocalInfo(code_item, true, 1, Callback, nullptr));
    625 }
    626 
    627 }  // namespace art
    628