blob: 6f99551e1afa4de354da1b591532d9bce0e944b7 [file] [log] [blame]
Carl Shapiro1fb86202011-06-27 17:43:13 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07003#include "dex_file.h"
Carl Shapiro1fb86202011-06-27 17:43:13 -07004
Elliott Hughes90a33692011-08-30 13:27:07 -07005#include "UniquePtr.h"
6#include "common_test.h"
7
Carl Shapiro1fb86202011-06-27 17:43:13 -07008namespace art {
9
Brian Carlstrom9f30b382011-08-28 22:41:38 -070010class DexFileTest : public CommonTest {};
11
12TEST_F(DexFileTest, Open) {
Elliott Hughes90a33692011-08-30 13:27:07 -070013 UniquePtr<const DexFile> dex(OpenTestDexFile("Nested"));
14 ASSERT_TRUE(dex.get() != NULL);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070015}
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070016
Brian Carlstrom9f30b382011-08-28 22:41:38 -070017// Although this is the same content logically as the Nested test dex,
18// the DexFileHeader test is sensitive to subtle changes in the
19// contents due to the checksum etc, so we embed the exact input here.
20//
21// class Nested {
22// class Inner {
23// }
24// }
25static const char kRawDex[] =
26 "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
27 "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
28 "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
29 "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
30 "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
31 "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
32 "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
33 "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
34 "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
35 "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
36 "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
37 "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
38 "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
39 "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
40 "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
41 "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
42
43TEST_F(DexFileTest, Header) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -070044 ScratchFile tmp;
45 UniquePtr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename()));
Elliott Hughes90a33692011-08-30 13:27:07 -070046 ASSERT_TRUE(raw.get() != NULL);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070047
Brian Carlstromf615a612011-07-23 12:50:34 -070048 const DexFile::Header& header = raw->GetHeader();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070049 // TODO: header.magic_
50 EXPECT_EQ(0x00d87910U, header.checksum_);
51 // TODO: header.signature_
52 EXPECT_EQ(904U, header.file_size_);
53 EXPECT_EQ(112U, header.header_size_);
54 EXPECT_EQ(0U, header.link_size_);
55 EXPECT_EQ(0U, header.link_off_);
56 EXPECT_EQ(15U, header.string_ids_size_);
57 EXPECT_EQ(112U, header.string_ids_off_);
58 EXPECT_EQ(7U, header.type_ids_size_);
59 EXPECT_EQ(172U, header.type_ids_off_);
60 EXPECT_EQ(2U, header.proto_ids_size_);
61 EXPECT_EQ(200U, header.proto_ids_off_);
62 EXPECT_EQ(1U, header.field_ids_size_);
63 EXPECT_EQ(224U, header.field_ids_off_);
64 EXPECT_EQ(3U, header.method_ids_size_);
65 EXPECT_EQ(232U, header.method_ids_off_);
66 EXPECT_EQ(2U, header.class_defs_size_);
67 EXPECT_EQ(256U, header.class_defs_off_);
68 EXPECT_EQ(584U, header.data_size_);
69 EXPECT_EQ(320U, header.data_off_);
70}
71
Brian Carlstrom9f30b382011-08-28 22:41:38 -070072TEST_F(DexFileTest, ClassDefs) {
Elliott Hughes90a33692011-08-30 13:27:07 -070073 UniquePtr<const DexFile> raw(OpenTestDexFile("Nested"));
74 ASSERT_TRUE(raw.get() != NULL);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070075 EXPECT_EQ(2U, raw->NumClassDefs());
76
Brian Carlstromf615a612011-07-23 12:50:34 -070077 const DexFile::ClassDef& c0 = raw->GetClassDef(0);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070078 EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
79
Brian Carlstromf615a612011-07-23 12:50:34 -070080 const DexFile::ClassDef& c1 = raw->GetClassDef(1);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070081 EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
Carl Shapiro1fb86202011-06-27 17:43:13 -070082}
83
Ian Rogers0571d352011-11-03 19:51:38 -070084TEST_F(DexFileTest, CreateMethodSignature) {
85 UniquePtr<const DexFile> raw(OpenTestDexFile("CreateMethodSignature"));
Elliott Hughes90a33692011-08-30 13:27:07 -070086 ASSERT_TRUE(raw.get() != NULL);
Carl Shapiro419ec7b2011-08-03 14:48:33 -070087 EXPECT_EQ(1U, raw->NumClassDefs());
88
89 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
Ian Rogers0571d352011-11-03 19:51:38 -070090 ASSERT_STREQ("LCreateMethodSignature;", raw->GetClassDescriptor(class_def));
Carl Shapiro419ec7b2011-08-03 14:48:33 -070091
92 const byte* class_data = raw->GetClassData(class_def);
93 ASSERT_TRUE(class_data != NULL);
Ian Rogers0571d352011-11-03 19:51:38 -070094 ClassDataItemIterator it(*raw.get(), class_data);
Carl Shapiro419ec7b2011-08-03 14:48:33 -070095
Ian Rogers0571d352011-11-03 19:51:38 -070096 EXPECT_EQ(1u, it.NumDirectMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -070097
Ian Rogers0571d352011-11-03 19:51:38 -070098 // Check the signature for the static initializer.
Carl Shapiro419ec7b2011-08-03 14:48:33 -070099 {
Ian Rogers0571d352011-11-03 19:51:38 -0700100 ASSERT_EQ(1U, it.NumDirectMethods());
101 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700102 uint32_t proto_idx = method_id.proto_idx_;
Ian Rogers0571d352011-11-03 19:51:38 -0700103 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700104 ASSERT_STREQ("<init>", name);
105 int32_t length;
Ian Rogers0571d352011-11-03 19:51:38 -0700106 std::string signature(raw->CreateMethodSignature(proto_idx, &length));
107 ASSERT_EQ("()V", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700108 }
109
110 // Check both virtual methods.
Ian Rogers0571d352011-11-03 19:51:38 -0700111 ASSERT_EQ(2U, it.NumVirtualMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700112 {
Ian Rogers0571d352011-11-03 19:51:38 -0700113 it.Next();
114 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700115
Ian Rogers0571d352011-11-03 19:51:38 -0700116 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700117 ASSERT_STREQ("m1", name);
118
119 uint32_t proto_idx = method_id.proto_idx_;
120 int32_t length;
Ian Rogers0571d352011-11-03 19:51:38 -0700121 std::string signature(raw->CreateMethodSignature(proto_idx, &length));
122 ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700123 }
124
125 {
Ian Rogers0571d352011-11-03 19:51:38 -0700126 it.Next();
127 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700128
Ian Rogers0571d352011-11-03 19:51:38 -0700129 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700130 ASSERT_STREQ("m2", name);
131
132 uint32_t proto_idx = method_id.proto_idx_;
133 int32_t length;
Ian Rogers0571d352011-11-03 19:51:38 -0700134 std::string signature(raw->CreateMethodSignature(proto_idx, &length));
135 ASSERT_EQ("(ZSC)LCreateMethodSignature;", signature);
136 }
137}
138
139TEST_F(DexFileTest, FindStringId) {
140 UniquePtr<const DexFile> raw(OpenTestDexFile("CreateMethodSignature"));
141 ASSERT_TRUE(raw.get() != NULL);
142 EXPECT_EQ(1U, raw->NumClassDefs());
143
144 const char* strings[] = { "LCreateMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
145 "D", "I", "J", NULL };
146 for (size_t i = 0; strings[i] != NULL; i++) {
147 const char* str = strings[i];
148 const DexFile::StringId* str_id = raw->FindStringId(str);
149 const char* dex_str = raw->GetStringData(*str_id);
150 EXPECT_STREQ(dex_str, str);
151 }
152}
153
154TEST_F(DexFileTest, FindTypeId) {
155 for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
156 const char* type_str = java_lang_dex_file_->StringByTypeIdx(i);
157 const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
158 ASSERT_TRUE(type_str_id != NULL);
159 uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
160 const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
161 ASSERT_TRUE(type_id != NULL);
162 EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id), i);
163 }
164}
165
166TEST_F(DexFileTest, FindProtoId) {
167 for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
168 const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
169 const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
170 std::vector<uint16_t> to_find_types;
171 if (to_find_tl != NULL) {
172 for (size_t j = 0; j < to_find_tl->Size(); j++) {
173 to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
174 }
175 }
176 const DexFile::ProtoId* found =
177 java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
178 ASSERT_TRUE(found != NULL);
179 EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
180 }
181}
182
183TEST_F(DexFileTest, FindMethodId) {
184 for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
185 const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
186 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
187 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
188 const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
189 const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
190 int32_t length;
191 ASSERT_TRUE(found != NULL) << "Didn't find method " << i << ": "
192 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
193 << java_lang_dex_file_->GetStringData(name)
194 << java_lang_dex_file_->CreateMethodSignature(to_find.proto_idx_, &length);
195 EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700196 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700197}
198
Carl Shapiro1fb86202011-06-27 17:43:13 -0700199} // namespace art