dex_file_test.cc revision 4e1d579d6401fef2dd57b16f8d406e33221a69d9
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
161fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
17578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_file.h"
181fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
19700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory>
20700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers
21e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "base/stl_util.h"
22e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "base/unix_file/fd_file.h"
23a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "common_runtime_test.h"
24e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "os.h"
25e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "scoped_thread_state_change.h"
26e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "thread-inl.h"
2790a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes
281fb8620309a4e94d11879aabc33364acfa733904Carl Shapironamespace art {
291fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
30a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass DexFileTest : public CommonRuntimeTest {};
319f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom
329f30b38d74990286ce27c3a45368f73dbe3638f0Brian CarlstromTEST_F(DexFileTest, Open) {
3333e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
344d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  const DexFile* dex(OpenTestDexFile("Nested"));
354d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  ASSERT_TRUE(dex != NULL);
367e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom}
377e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom
38a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromstatic const byte kBase64Map[256] = {
39a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
40a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
41a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
42a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
43a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
44a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
45a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  // NOLINT
46a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom   19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,  // NOLINT
47a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
48a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom   37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  // NOLINT
49a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom   49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,  // NOLINT
50a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
51a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
52a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
53a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
54a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
55a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
56a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
57a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
58a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
59a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
60a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255
61a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom};
62a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
63a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromstatic inline byte* DecodeBase64(const char* src, size_t* dst_size) {
64a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  std::vector<byte> tmp;
65a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  uint32_t t = 0, y = 0;
66a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  int g = 3;
67a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  for (size_t i = 0; src[i] != '\0'; ++i) {
68a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    byte c = kBase64Map[src[i] & 0xFF];
69a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    if (c == 255) continue;
70a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    // the final = symbols are read and used to trim the remaining bytes
71a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    if (c == 254) {
72a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      c = 0;
73a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      // prevent g < 0 which would potentially allow an overflow later
74a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      if (--g < 0) {
75a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom        *dst_size = 0;
76a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom        return nullptr;
77a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      }
78a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    } else if (g != 3) {
79a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      // we only allow = to be at the end
80a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      *dst_size = 0;
81a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      return nullptr;
82a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    }
83a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    t = (t << 6) | c;
84a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    if (++y == 4) {
85a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      tmp.push_back((t >> 16) & 255);
86a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      if (g > 1) {
87a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom        tmp.push_back((t >> 8) & 255);
88a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      }
89a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      if (g > 2) {
90a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom        tmp.push_back(t & 255);
91a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      }
92a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      y = t = 0;
93a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    }
94a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
95a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  if (y != 0) {
96a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    *dst_size = 0;
97a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    return nullptr;
98a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
99700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<byte[]> dst(new byte[tmp.size()]);
100a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  if (dst_size != nullptr) {
101a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    *dst_size = tmp.size();
102a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  } else {
103a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    *dst_size = 0;
104a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
105a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  std::copy(tmp.begin(), tmp.end(), dst.get());
106a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  return dst.release();
107a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom}
108a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
1099f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom// Although this is the same content logically as the Nested test dex,
1109f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom// the DexFileHeader test is sensitive to subtle changes in the
1119f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom// contents due to the checksum etc, so we embed the exact input here.
1129f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom//
1139f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom// class Nested {
1149f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom//     class Inner {
1159f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom//     }
1169f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom// }
1179f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstromstatic const char kRawDex[] =
1189f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
1199f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
1209f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
1219f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
1229f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
1239f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
1249f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
1259f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
1269f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
1279f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
1289f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
1299f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
1309f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
1319f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
1329f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
1339f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
1349f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom
13533e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogersstatic const DexFile* OpenDexFileBase64(const char* base64,
1368d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                        const char* location) {
13733e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  // decode base64
13833e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CHECK(base64 != NULL);
13933e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  size_t length;
140700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<byte[]> dex_bytes(DecodeBase64(base64, &length));
14133e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CHECK(dex_bytes.get() != NULL);
14233e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers
14333e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  // write to provided file
144700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<File> file(OS::CreateEmptyFile(location));
14533e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CHECK(file.get() != NULL);
14633e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  if (!file->WriteFully(dex_bytes.get(), length)) {
14733e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    PLOG(FATAL) << "Failed to write base64 as dex file";
14833e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  }
14933e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  file.reset();
15033e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers
15133e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  // read dex file
15233e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
1538d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  std::string error_msg;
154833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe  std::vector<const DexFile*> tmp;
155833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe  bool success = DexFile::Open(location, location, &error_msg, &tmp);
156833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe  CHECK(success) << error_msg;
157833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe  EXPECT_EQ(1U, tmp.size());
158833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe  const DexFile* dex_file = tmp[0];
159e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom  EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
160e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom  EXPECT_TRUE(dex_file->IsReadOnly());
16133e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  return dex_file;
16233e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers}
16333e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers
1649f30b38d74990286ce27c3a45368f73dbe3638f0Brian CarlstromTEST_F(DexFileTest, Header) {
16533f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  ScratchFile tmp;
166700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
16790a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes  ASSERT_TRUE(raw.get() != NULL);
1687e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom
169f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  const DexFile::Header& header = raw->GetHeader();
1707e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  // TODO: header.magic_
1717e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(0x00d87910U, header.checksum_);
1727e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  // TODO: header.signature_
1737e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(904U, header.file_size_);
1747e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(112U, header.header_size_);
1757e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(0U, header.link_size_);
1767e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(0U, header.link_off_);
1777e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(15U, header.string_ids_size_);
1787e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(112U, header.string_ids_off_);
1797e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(7U, header.type_ids_size_);
1807e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(172U, header.type_ids_off_);
1817e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(2U, header.proto_ids_size_);
1827e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(200U, header.proto_ids_off_);
1837e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(1U, header.field_ids_size_);
1847e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(224U, header.field_ids_off_);
1857e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(3U, header.method_ids_size_);
1867e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(232U, header.method_ids_off_);
1877e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(2U, header.class_defs_size_);
1887e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(256U, header.class_defs_off_);
1897e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(584U, header.data_size_);
1907e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(320U, header.data_off_);
1915b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom
1925b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  EXPECT_EQ(header.checksum_, raw->GetLocationChecksum());
1935b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom}
1945b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom
1955b332c89fa3fdd7dc184b22c2587d28af304d019Brian CarlstromTEST_F(DexFileTest, GetLocationChecksum) {
19633e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
1975b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  const DexFile* raw(OpenTestDexFile("Main"));
1985b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
1995b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom}
2005b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom
2015b332c89fa3fdd7dc184b22c2587d28af304d019Brian CarlstromTEST_F(DexFileTest, GetChecksum) {
2025b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  uint32_t checksum;
20333e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
2048d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  std::string error_msg;
2058d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  EXPECT_TRUE(DexFile::GetChecksum(GetLibCoreDexFileName().c_str(), &checksum, &error_msg))
2068d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      << error_msg;
2075b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksum);
2087e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom}
2097e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom
2109f30b38d74990286ce27c3a45368f73dbe3638f0Brian CarlstromTEST_F(DexFileTest, ClassDefs) {
21133e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
2124d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  const DexFile* raw(OpenTestDexFile("Nested"));
2134d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  ASSERT_TRUE(raw != NULL);
2147e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(2U, raw->NumClassDefs());
215578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
216f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  const DexFile::ClassDef& c0 = raw->GetClassDef(0);
2177e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
218578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
219f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  const DexFile::ClassDef& c1 = raw->GetClassDef(1);
2207e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
2211fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro}
2221fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
223d91d6d6a80748f277fd938a412211e5af28913b1Ian RogersTEST_F(DexFileTest, GetMethodSignature) {
22433e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
225d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const DexFile* raw(OpenTestDexFile("GetMethodSignature"));
2264d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  ASSERT_TRUE(raw != NULL);
227419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  EXPECT_EQ(1U, raw->NumClassDefs());
228419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
229419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  const DexFile::ClassDef& class_def = raw->GetClassDef(0);
230d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
231419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
232419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  const byte* class_data = raw->GetClassData(class_def);
233419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  ASSERT_TRUE(class_data != NULL);
2344d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  ClassDataItemIterator it(*raw, class_data);
235419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
2360571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  EXPECT_EQ(1u, it.NumDirectMethods());
237419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
2380571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  // Check the signature for the static initializer.
239419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  {
2400571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    ASSERT_EQ(1U, it.NumDirectMethods());
2410571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
2420571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const char* name = raw->StringDataByIdx(method_id.name_idx_);
243419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro    ASSERT_STREQ("<init>", name);
244d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers    std::string signature(raw->GetMethodSignature(method_id).ToString());
2450571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    ASSERT_EQ("()V", signature);
246419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  }
247419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
248419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  // Check both virtual methods.
2490571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  ASSERT_EQ(2U, it.NumVirtualMethods());
250419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  {
2510571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
2520571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
253419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
2540571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const char* name = raw->StringDataByIdx(method_id.name_idx_);
255419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro    ASSERT_STREQ("m1", name);
256419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
257d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers    std::string signature(raw->GetMethodSignature(method_id).ToString());
2580571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
259419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  }
260419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
261419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  {
2620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
2630571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
264419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
2650571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const char* name = raw->StringDataByIdx(method_id.name_idx_);
266419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro    ASSERT_STREQ("m2", name);
267419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
268d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers    std::string signature(raw->GetMethodSignature(method_id).ToString());
269d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers    ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
2700571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
2710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
2720571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
2730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersTEST_F(DexFileTest, FindStringId) {
27433e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
275d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const DexFile* raw(OpenTestDexFile("GetMethodSignature"));
2764d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  ASSERT_TRUE(raw != NULL);
2770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  EXPECT_EQ(1U, raw->NumClassDefs());
2780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
279d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
2800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      "D", "I", "J", NULL };
2810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  for (size_t i = 0; strings[i] != NULL; i++) {
2820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const char* str = strings[i];
2830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::StringId* str_id = raw->FindStringId(str);
2840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const char* dex_str = raw->GetStringData(*str_id);
2850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    EXPECT_STREQ(dex_str, str);
2860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
2870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
2880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
2890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersTEST_F(DexFileTest, FindTypeId) {
2900571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
2910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const char* type_str = java_lang_dex_file_->StringByTypeIdx(i);
2920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
2930571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    ASSERT_TRUE(type_str_id != NULL);
2940571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
2950571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
2960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    ASSERT_TRUE(type_id != NULL);
2970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id), i);
2980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
2990571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
3000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
3010571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersTEST_F(DexFileTest, FindProtoId) {
3020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
3030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
3040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
3050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    std::vector<uint16_t> to_find_types;
3060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    if (to_find_tl != NULL) {
3070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      for (size_t j = 0; j < to_find_tl->Size(); j++) {
3080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers        to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
3090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      }
3100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    }
3110571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::ProtoId* found =
3120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers        java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
3130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    ASSERT_TRUE(found != NULL);
3140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
3150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
3160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
3170571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
3180571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersTEST_F(DexFileTest, FindMethodId) {
3190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
3200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
3210571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
3220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
3230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
3240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
3250571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    ASSERT_TRUE(found != NULL) << "Didn't find method " << i << ": "
3260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers        << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
3270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers        << java_lang_dex_file_->GetStringData(name)
328d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers        << java_lang_dex_file_->GetMethodSignature(to_find);
3290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
330419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  }
331419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro}
332419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
3339b1a4f425711c26d0465d54a1cb95ec4a813322aIan RogersTEST_F(DexFileTest, FindFieldId) {
3349b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers  for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
3359b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
3369b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
3379b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
3389b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
3399b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
3409b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    ASSERT_TRUE(found != NULL) << "Didn't find field " << i << ": "
3419b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers        << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
3429b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers        << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
3439b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers        << java_lang_dex_file_->GetStringData(name);
3449b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
3459b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers  }
3469b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers}
3479b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers
3484e1d579d6401fef2dd57b16f8d406e33221a69d9Calin JuravleTEST_F(DexFileTest, GetMultiDexClassesDexName) {
3494e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  std::string dex_location_str = "/system/app/framework.jar";
3504e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  const char* dex_location = dex_location_str.c_str();
3514e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ("/system/app/framework.jar", DexFile::GetMultiDexClassesDexName(0, dex_location));
3524e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ("/system/app/framework.jar:classes2.dex", DexFile::GetMultiDexClassesDexName(1, dex_location));
3534e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ("/system/app/framework.jar:classes101.dex", DexFile::GetMultiDexClassesDexName(100, dex_location));
3544e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle}
3554e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
3564e1d579d6401fef2dd57b16f8d406e33221a69d9Calin JuravleTEST_F(DexFileTest, GetDexCanonicalLocation) {
3574e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ScratchFile file;
3584e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  std::string dex_location = file.GetFilename();
3594e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
3604e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ(file.GetFilename(), DexFile::GetDexCanonicalLocation(dex_location.c_str()));
3614e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  std::string multidex_location = DexFile::GetMultiDexClassesDexName(1, dex_location.c_str());
3624e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location.c_str()));
3634e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
3644e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  std::string dex_location_sym = dex_location + "symlink";
3654e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
3664e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
3674e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location_sym.c_str()));
3684e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
3694e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  std::string multidex_location_sym = DexFile::GetMultiDexClassesDexName(1, dex_location_sym.c_str());
3704e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location_sym.c_str()));
3714e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
3724e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
3734e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle}
3744e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
3751fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro}  // namespace art
376