• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <fcntl.h>
20 #include <limits.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/file.h>
25 #include <sys/stat.h>
26 
27 #include "base/logging.h"
28 #include "base/stringprintf.h"
29 #include "class_linker.h"
30 #include "dex_file-inl.h"
31 #include "dex_file_verifier.h"
32 #include "globals.h"
33 #include "leb128.h"
34 #include "mirror/art_field-inl.h"
35 #include "mirror/art_method-inl.h"
36 #include "mirror/string.h"
37 #include "os.h"
38 #include "safe_map.h"
39 #include "thread.h"
40 #include "UniquePtr.h"
41 #include "utf.h"
42 #include "utils.h"
43 #include "well_known_classes.h"
44 #include "zip_archive.h"
45 
46 namespace art {
47 
48 const byte DexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
49 const byte DexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' };
50 
FindInClassPath(const char * descriptor,const ClassPath & class_path)51 DexFile::ClassPathEntry DexFile::FindInClassPath(const char* descriptor,
52                                                  const ClassPath& class_path) {
53   for (size_t i = 0; i != class_path.size(); ++i) {
54     const DexFile* dex_file = class_path[i];
55     const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor);
56     if (dex_class_def != NULL) {
57       return ClassPathEntry(dex_file, dex_class_def);
58     }
59   }
60   // TODO: remove reinterpret_cast when issue with -std=gnu++0x host issue resolved
61   return ClassPathEntry(reinterpret_cast<const DexFile*>(NULL),
62                         reinterpret_cast<const DexFile::ClassDef*>(NULL));
63 }
64 
OpenAndReadMagic(const std::string & filename,uint32_t * magic)65 int OpenAndReadMagic(const std::string& filename, uint32_t* magic) {
66   CHECK(magic != NULL);
67   int fd = open(filename.c_str(), O_RDONLY, 0);
68   if (fd == -1) {
69     PLOG(WARNING) << "Unable to open '" << filename << "'";
70     return -1;
71   }
72   int n = TEMP_FAILURE_RETRY(read(fd, magic, sizeof(*magic)));
73   if (n != sizeof(*magic)) {
74     PLOG(ERROR) << "Failed to find magic in '" << filename << "'";
75     return -1;
76   }
77   if (lseek(fd, 0, SEEK_SET) != 0) {
78     PLOG(ERROR) << "Failed to seek to beginning of file '" << filename << "'";
79     return -1;
80   }
81   return fd;
82 }
83 
GetChecksum(const std::string & filename,uint32_t * checksum)84 bool DexFile::GetChecksum(const std::string& filename, uint32_t* checksum) {
85   CHECK(checksum != NULL);
86   uint32_t magic;
87   int fd = OpenAndReadMagic(filename, &magic);
88   if (fd == -1) {
89     return false;
90   }
91   if (IsZipMagic(magic)) {
92     UniquePtr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(fd));
93     if (zip_archive.get() == NULL) {
94       return false;
95     }
96     UniquePtr<ZipEntry> zip_entry(zip_archive->Find(kClassesDex));
97     if (zip_entry.get() == NULL) {
98       LOG(ERROR) << "Zip archive '" << filename << "' doesn't contain " << kClassesDex;
99       return false;
100     }
101     *checksum = zip_entry->GetCrc32();
102     return true;
103   }
104   if (IsDexMagic(magic)) {
105     UniquePtr<const DexFile> dex_file(DexFile::OpenFile(fd, filename, false));
106     if (dex_file.get() == NULL) {
107       return false;
108     }
109     *checksum = dex_file->GetHeader().checksum_;
110     return true;
111   }
112   LOG(ERROR) << "Expected valid zip or dex file: " << filename;
113   return false;
114 }
115 
Open(const std::string & filename,const std::string & location)116 const DexFile* DexFile::Open(const std::string& filename,
117                              const std::string& location) {
118   uint32_t magic;
119   int fd = OpenAndReadMagic(filename, &magic);
120   if (fd == -1) {
121     return NULL;
122   }
123   if (IsZipMagic(magic)) {
124     return DexFile::OpenZip(fd, location);
125   }
126   if (IsDexMagic(magic)) {
127     return DexFile::OpenFile(fd, location, true);
128   }
129   LOG(ERROR) << "Expected valid zip or dex file: " << filename;
130   return NULL;
131 }
132 
GetPermissions() const133 int DexFile::GetPermissions() const {
134   if (mem_map_.get() == NULL) {
135     return 0;
136   } else {
137     return mem_map_->GetProtect();
138   }
139 }
140 
IsReadOnly() const141 bool DexFile::IsReadOnly() const {
142   return GetPermissions() == PROT_READ;
143 }
144 
EnableWrite() const145 bool DexFile::EnableWrite() const {
146   CHECK(IsReadOnly());
147   if (mem_map_.get() == NULL) {
148     return false;
149   } else {
150     return mem_map_->Protect(PROT_READ | PROT_WRITE);
151   }
152 }
153 
DisableWrite() const154 bool DexFile::DisableWrite() const {
155   CHECK(!IsReadOnly());
156   if (mem_map_.get() == NULL) {
157     return false;
158   } else {
159     return mem_map_->Protect(PROT_READ);
160   }
161 }
162 
OpenFile(int fd,const std::string & location,bool verify)163 const DexFile* DexFile::OpenFile(int fd,
164                                  const std::string& location,
165                                  bool verify) {
166   CHECK(!location.empty());
167   struct stat sbuf;
168   memset(&sbuf, 0, sizeof(sbuf));
169   if (fstat(fd, &sbuf) == -1) {
170     PLOG(ERROR) << "fstat \"" << location << "\" failed";
171     close(fd);
172     return NULL;
173   }
174   if (S_ISDIR(sbuf.st_mode)) {
175     LOG(ERROR) << "attempt to mmap directory \"" << location << "\"";
176     return NULL;
177   }
178   size_t length = sbuf.st_size;
179   UniquePtr<MemMap> map(MemMap::MapFile(length, PROT_READ, MAP_PRIVATE, fd, 0));
180   if (map.get() == NULL) {
181     LOG(ERROR) << "mmap \"" << location << "\" failed";
182     close(fd);
183     return NULL;
184   }
185   close(fd);
186 
187   if (map->Size() < sizeof(DexFile::Header)) {
188     LOG(ERROR) << "Failed to open dex file '" << location << "' that is too short to have a header";
189     return NULL;
190   }
191 
192   const Header* dex_header = reinterpret_cast<const Header*>(map->Begin());
193 
194   const DexFile* dex_file = OpenMemory(location, dex_header->checksum_, map.release());
195   if (dex_file == NULL) {
196     LOG(ERROR) << "Failed to open dex file '" << location << "' from memory";
197     return NULL;
198   }
199 
200   if (verify && !DexFileVerifier::Verify(dex_file, dex_file->Begin(), dex_file->Size())) {
201     LOG(ERROR) << "Failed to verify dex file '" << location << "'";
202     return NULL;
203   }
204 
205   return dex_file;
206 }
207 
208 const char* DexFile::kClassesDex = "classes.dex";
209 
OpenZip(int fd,const std::string & location)210 const DexFile* DexFile::OpenZip(int fd, const std::string& location) {
211   UniquePtr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(fd));
212   if (zip_archive.get() == NULL) {
213     LOG(ERROR) << "Failed to open " << location << " when looking for classes.dex";
214     return NULL;
215   }
216   return DexFile::Open(*zip_archive.get(), location);
217 }
218 
OpenMemory(const std::string & location,uint32_t location_checksum,MemMap * mem_map)219 const DexFile* DexFile::OpenMemory(const std::string& location,
220                                    uint32_t location_checksum,
221                                    MemMap* mem_map) {
222   return OpenMemory(mem_map->Begin(),
223                     mem_map->Size(),
224                     location,
225                     location_checksum,
226                     mem_map);
227 }
228 
Open(const ZipArchive & zip_archive,const std::string & location)229 const DexFile* DexFile::Open(const ZipArchive& zip_archive, const std::string& location) {
230   CHECK(!location.empty());
231   UniquePtr<ZipEntry> zip_entry(zip_archive.Find(kClassesDex));
232   if (zip_entry.get() == NULL) {
233     LOG(ERROR) << "Failed to find classes.dex within '" << location << "'";
234     return NULL;
235   }
236   UniquePtr<MemMap> map(zip_entry->ExtractToMemMap(kClassesDex));
237   if (map.get() == NULL) {
238     LOG(ERROR) << "Failed to extract '" << kClassesDex << "' from '" << location << "'";
239     return NULL;
240   }
241   UniquePtr<const DexFile> dex_file(OpenMemory(location, zip_entry->GetCrc32(), map.release()));
242   if (dex_file.get() == NULL) {
243     LOG(ERROR) << "Failed to open dex file '" << location << "' from memory";
244     return NULL;
245   }
246   if (!DexFileVerifier::Verify(dex_file.get(), dex_file->Begin(), dex_file->Size())) {
247     LOG(ERROR) << "Failed to verify dex file '" << location << "'";
248     return NULL;
249   }
250   if (!dex_file->DisableWrite()) {
251     LOG(ERROR) << "Failed to make dex file read only '" << location << "'";
252     return NULL;
253   }
254   CHECK(dex_file->IsReadOnly()) << location;
255   return dex_file.release();
256 }
257 
OpenMemory(const byte * base,size_t size,const std::string & location,uint32_t location_checksum,MemMap * mem_map)258 const DexFile* DexFile::OpenMemory(const byte* base,
259                                    size_t size,
260                                    const std::string& location,
261                                    uint32_t location_checksum,
262                                    MemMap* mem_map) {
263   CHECK_ALIGNED(base, 4);  // various dex file structures must be word aligned
264   UniquePtr<DexFile> dex_file(new DexFile(base, size, location, location_checksum, mem_map));
265   if (!dex_file->Init()) {
266     return NULL;
267   } else {
268     return dex_file.release();
269   }
270 }
271 
~DexFile()272 DexFile::~DexFile() {
273   // We don't call DeleteGlobalRef on dex_object_ because we're only called by DestroyJavaVM, and
274   // that's only called after DetachCurrentThread, which means there's no JNIEnv. We could
275   // re-attach, but cleaning up these global references is not obviously useful. It's not as if
276   // the global reference table is otherwise empty!
277 }
278 
Init()279 bool DexFile::Init() {
280   InitMembers();
281   if (!CheckMagicAndVersion()) {
282     return false;
283   }
284   return true;
285 }
286 
InitMembers()287 void DexFile::InitMembers() {
288   const byte* b = begin_;
289   header_ = reinterpret_cast<const Header*>(b);
290   const Header* h = header_;
291   string_ids_ = reinterpret_cast<const StringId*>(b + h->string_ids_off_);
292   type_ids_ = reinterpret_cast<const TypeId*>(b + h->type_ids_off_);
293   field_ids_ = reinterpret_cast<const FieldId*>(b + h->field_ids_off_);
294   method_ids_ = reinterpret_cast<const MethodId*>(b + h->method_ids_off_);
295   proto_ids_ = reinterpret_cast<const ProtoId*>(b + h->proto_ids_off_);
296   class_defs_ = reinterpret_cast<const ClassDef*>(b + h->class_defs_off_);
297 }
298 
CheckMagicAndVersion() const299 bool DexFile::CheckMagicAndVersion() const {
300   CHECK(header_->magic_ != NULL) << GetLocation();
301   if (!IsMagicValid(header_->magic_)) {
302     LOG(ERROR) << "Unrecognized magic number in "  << GetLocation() << ":"
303             << " " << header_->magic_[0]
304             << " " << header_->magic_[1]
305             << " " << header_->magic_[2]
306             << " " << header_->magic_[3];
307     return false;
308   }
309   if (!IsVersionValid(header_->magic_)) {
310     LOG(ERROR) << "Unrecognized version number in "  << GetLocation() << ":"
311             << " " << header_->magic_[4]
312             << " " << header_->magic_[5]
313             << " " << header_->magic_[6]
314             << " " << header_->magic_[7];
315     return false;
316   }
317   return true;
318 }
319 
IsMagicValid(const byte * magic)320 bool DexFile::IsMagicValid(const byte* magic) {
321   return (memcmp(magic, kDexMagic, sizeof(kDexMagic)) == 0);
322 }
323 
IsVersionValid(const byte * magic)324 bool DexFile::IsVersionValid(const byte* magic) {
325   const byte* version = &magic[sizeof(kDexMagic)];
326   return (memcmp(version, kDexMagicVersion, sizeof(kDexMagicVersion)) == 0);
327 }
328 
GetVersion() const329 uint32_t DexFile::GetVersion() const {
330   const char* version = reinterpret_cast<const char*>(&GetHeader().magic_[sizeof(kDexMagic)]);
331   return atoi(version);
332 }
333 
FindClassDef(const char * descriptor) const334 const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor) const {
335   size_t num_class_defs = NumClassDefs();
336   if (num_class_defs == 0) {
337     return NULL;
338   }
339   const StringId* string_id = FindStringId(descriptor);
340   if (string_id == NULL) {
341     return NULL;
342   }
343   const TypeId* type_id = FindTypeId(GetIndexForStringId(*string_id));
344   if (type_id == NULL) {
345     return NULL;
346   }
347   uint16_t type_idx = GetIndexForTypeId(*type_id);
348   for (size_t i = 0; i < num_class_defs; ++i) {
349     const ClassDef& class_def = GetClassDef(i);
350     if (class_def.class_idx_ == type_idx) {
351       return &class_def;
352     }
353   }
354   return NULL;
355 }
356 
FindClassDef(uint16_t type_idx) const357 const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const {
358   size_t num_class_defs = NumClassDefs();
359   for (size_t i = 0; i < num_class_defs; ++i) {
360     const ClassDef& class_def = GetClassDef(i);
361     if (class_def.class_idx_ == type_idx) {
362       return &class_def;
363     }
364   }
365   return NULL;
366 }
367 
FindFieldId(const DexFile::TypeId & declaring_klass,const DexFile::StringId & name,const DexFile::TypeId & type) const368 const DexFile::FieldId* DexFile::FindFieldId(const DexFile::TypeId& declaring_klass,
369                                               const DexFile::StringId& name,
370                                               const DexFile::TypeId& type) const {
371   // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx
372   const uint16_t class_idx = GetIndexForTypeId(declaring_klass);
373   const uint32_t name_idx = GetIndexForStringId(name);
374   const uint16_t type_idx = GetIndexForTypeId(type);
375   int32_t lo = 0;
376   int32_t hi = NumFieldIds() - 1;
377   while (hi >= lo) {
378     int32_t mid = (hi + lo) / 2;
379     const DexFile::FieldId& field = GetFieldId(mid);
380     if (class_idx > field.class_idx_) {
381       lo = mid + 1;
382     } else if (class_idx < field.class_idx_) {
383       hi = mid - 1;
384     } else {
385       if (name_idx > field.name_idx_) {
386         lo = mid + 1;
387       } else if (name_idx < field.name_idx_) {
388         hi = mid - 1;
389       } else {
390         if (type_idx > field.type_idx_) {
391           lo = mid + 1;
392         } else if (type_idx < field.type_idx_) {
393           hi = mid - 1;
394         } else {
395           return &field;
396         }
397       }
398     }
399   }
400   return NULL;
401 }
402 
FindMethodId(const DexFile::TypeId & declaring_klass,const DexFile::StringId & name,const DexFile::ProtoId & signature) const403 const DexFile::MethodId* DexFile::FindMethodId(const DexFile::TypeId& declaring_klass,
404                                                const DexFile::StringId& name,
405                                                const DexFile::ProtoId& signature) const {
406   // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx
407   const uint16_t class_idx = GetIndexForTypeId(declaring_klass);
408   const uint32_t name_idx = GetIndexForStringId(name);
409   const uint16_t proto_idx = GetIndexForProtoId(signature);
410   int32_t lo = 0;
411   int32_t hi = NumMethodIds() - 1;
412   while (hi >= lo) {
413     int32_t mid = (hi + lo) / 2;
414     const DexFile::MethodId& method = GetMethodId(mid);
415     if (class_idx > method.class_idx_) {
416       lo = mid + 1;
417     } else if (class_idx < method.class_idx_) {
418       hi = mid - 1;
419     } else {
420       if (name_idx > method.name_idx_) {
421         lo = mid + 1;
422       } else if (name_idx < method.name_idx_) {
423         hi = mid - 1;
424       } else {
425         if (proto_idx > method.proto_idx_) {
426           lo = mid + 1;
427         } else if (proto_idx < method.proto_idx_) {
428           hi = mid - 1;
429         } else {
430           return &method;
431         }
432       }
433     }
434   }
435   return NULL;
436 }
437 
FindStringId(const char * string) const438 const DexFile::StringId* DexFile::FindStringId(const char* string) const {
439   int32_t lo = 0;
440   int32_t hi = NumStringIds() - 1;
441   while (hi >= lo) {
442     int32_t mid = (hi + lo) / 2;
443     uint32_t length;
444     const DexFile::StringId& str_id = GetStringId(mid);
445     const char* str = GetStringDataAndLength(str_id, &length);
446     int compare = CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(string, str);
447     if (compare > 0) {
448       lo = mid + 1;
449     } else if (compare < 0) {
450       hi = mid - 1;
451     } else {
452       return &str_id;
453     }
454   }
455   return NULL;
456 }
457 
FindStringId(const uint16_t * string) const458 const DexFile::StringId* DexFile::FindStringId(const uint16_t* string) const {
459   int32_t lo = 0;
460   int32_t hi = NumStringIds() - 1;
461   while (hi >= lo) {
462     int32_t mid = (hi + lo) / 2;
463     uint32_t length;
464     const DexFile::StringId& str_id = GetStringId(mid);
465     const char* str = GetStringDataAndLength(str_id, &length);
466     int compare = CompareModifiedUtf8ToUtf16AsCodePointValues(str, string);
467     if (compare > 0) {
468       lo = mid + 1;
469     } else if (compare < 0) {
470       hi = mid - 1;
471     } else {
472       return &str_id;
473     }
474   }
475   return NULL;
476 }
477 
FindTypeId(uint32_t string_idx) const478 const DexFile::TypeId* DexFile::FindTypeId(uint32_t string_idx) const {
479   int32_t lo = 0;
480   int32_t hi = NumTypeIds() - 1;
481   while (hi >= lo) {
482     int32_t mid = (hi + lo) / 2;
483     const TypeId& type_id = GetTypeId(mid);
484     if (string_idx > type_id.descriptor_idx_) {
485       lo = mid + 1;
486     } else if (string_idx < type_id.descriptor_idx_) {
487       hi = mid - 1;
488     } else {
489       return &type_id;
490     }
491   }
492   return NULL;
493 }
494 
FindProtoId(uint16_t return_type_idx,const std::vector<uint16_t> & signature_type_idxs) const495 const DexFile::ProtoId* DexFile::FindProtoId(uint16_t return_type_idx,
496                                          const std::vector<uint16_t>& signature_type_idxs) const {
497   int32_t lo = 0;
498   int32_t hi = NumProtoIds() - 1;
499   while (hi >= lo) {
500     int32_t mid = (hi + lo) / 2;
501     const DexFile::ProtoId& proto = GetProtoId(mid);
502     int compare = return_type_idx - proto.return_type_idx_;
503     if (compare == 0) {
504       DexFileParameterIterator it(*this, proto);
505       size_t i = 0;
506       while (it.HasNext() && i < signature_type_idxs.size() && compare == 0) {
507         compare = signature_type_idxs[i] - it.GetTypeIdx();
508         it.Next();
509         i++;
510       }
511       if (compare == 0) {
512         if (it.HasNext()) {
513           compare = -1;
514         } else if (i < signature_type_idxs.size()) {
515           compare = 1;
516         }
517       }
518     }
519     if (compare > 0) {
520       lo = mid + 1;
521     } else if (compare < 0) {
522       hi = mid - 1;
523     } else {
524       return &proto;
525     }
526   }
527   return NULL;
528 }
529 
530 // Given a signature place the type ids into the given vector
CreateTypeList(uint16_t * return_type_idx,std::vector<uint16_t> * param_type_idxs,const std::string & signature) const531 bool DexFile::CreateTypeList(uint16_t* return_type_idx, std::vector<uint16_t>* param_type_idxs,
532                              const std::string& signature) const {
533   if (signature[0] != '(') {
534     return false;
535   }
536   size_t offset = 1;
537   size_t end = signature.size();
538   bool process_return = false;
539   while (offset < end) {
540     char c = signature[offset];
541     offset++;
542     if (c == ')') {
543       process_return = true;
544       continue;
545     }
546     std::string descriptor;
547     descriptor += c;
548     while (c == '[') {  // process array prefix
549       if (offset >= end) {  // expect some descriptor following [
550         return false;
551       }
552       c = signature[offset];
553       offset++;
554       descriptor += c;
555     }
556     if (c == 'L') {  // process type descriptors
557       do {
558         if (offset >= end) {  // unexpected early termination of descriptor
559           return false;
560         }
561         c = signature[offset];
562         offset++;
563         descriptor += c;
564       } while (c != ';');
565     }
566     const DexFile::StringId* string_id = FindStringId(descriptor.c_str());
567     if (string_id == NULL) {
568       return false;
569     }
570     const DexFile::TypeId* type_id = FindTypeId(GetIndexForStringId(*string_id));
571     if (type_id == NULL) {
572       return false;
573     }
574     uint16_t type_idx = GetIndexForTypeId(*type_id);
575     if (!process_return) {
576       param_type_idxs->push_back(type_idx);
577     } else {
578       *return_type_idx = type_idx;
579       return offset == end;  // return true if the signature had reached a sensible end
580     }
581   }
582   return false;  // failed to correctly parse return type
583 }
584 
585 // Materializes the method descriptor for a method prototype.  Method
586 // descriptors are not stored directly in the dex file.  Instead, one
587 // must assemble the descriptor from references in the prototype.
CreateMethodSignature(uint32_t proto_idx,int32_t * unicode_length) const588 std::string DexFile::CreateMethodSignature(uint32_t proto_idx, int32_t* unicode_length) const {
589   const ProtoId& proto_id = GetProtoId(proto_idx);
590   std::string descriptor;
591   descriptor.push_back('(');
592   const TypeList* type_list = GetProtoParameters(proto_id);
593   size_t parameter_length = 0;
594   if (type_list != NULL) {
595     // A non-zero number of arguments.  Append the type names.
596     for (size_t i = 0; i < type_list->Size(); ++i) {
597       const TypeItem& type_item = type_list->GetTypeItem(i);
598       uint32_t type_idx = type_item.type_idx_;
599       uint32_t type_length;
600       const char* name = StringByTypeIdx(type_idx, &type_length);
601       parameter_length += type_length;
602       descriptor.append(name);
603     }
604   }
605   descriptor.push_back(')');
606   uint32_t return_type_idx = proto_id.return_type_idx_;
607   uint32_t return_type_length;
608   const char* name = StringByTypeIdx(return_type_idx, &return_type_length);
609   descriptor.append(name);
610   if (unicode_length != NULL) {
611     *unicode_length = parameter_length + return_type_length + 2;  // 2 for ( and )
612   }
613   return descriptor;
614 }
615 
GetLineNumFromPC(const mirror::ArtMethod * method,uint32_t rel_pc) const616 int32_t DexFile::GetLineNumFromPC(const mirror::ArtMethod* method, uint32_t rel_pc) const {
617   // For native method, lineno should be -2 to indicate it is native. Note that
618   // "line number == -2" is how libcore tells from StackTraceElement.
619   if (method->GetCodeItemOffset() == 0) {
620     return -2;
621   }
622 
623   const CodeItem* code_item = GetCodeItem(method->GetCodeItemOffset());
624   DCHECK(code_item != NULL) << PrettyMethod(method) << " " << GetLocation();
625 
626   // A method with no line number info should return -1
627   LineNumFromPcContext context(rel_pc, -1);
628   DecodeDebugInfo(code_item, method->IsStatic(), method->GetDexMethodIndex(), LineNumForPcCb,
629                   NULL, &context);
630   return context.line_num_;
631 }
632 
FindTryItem(const CodeItem & code_item,uint32_t address)633 int32_t DexFile::FindTryItem(const CodeItem &code_item, uint32_t address) {
634   // Note: Signed type is important for max and min.
635   int32_t min = 0;
636   int32_t max = code_item.tries_size_ - 1;
637 
638   while (min <= max) {
639     int32_t mid = min + ((max - min) / 2);
640 
641     const art::DexFile::TryItem* ti = GetTryItems(code_item, mid);
642     uint32_t start = ti->start_addr_;
643     uint32_t end = start + ti->insn_count_;
644 
645     if (address < start) {
646       max = mid - 1;
647     } else if (address >= end) {
648       min = mid + 1;
649     } else {  // We have a winner!
650       return mid;
651     }
652   }
653   // No match.
654   return -1;
655 }
656 
FindCatchHandlerOffset(const CodeItem & code_item,uint32_t address)657 int32_t DexFile::FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address) {
658   int32_t try_item = FindTryItem(code_item, address);
659   if (try_item == -1) {
660     return -1;
661   } else {
662     return DexFile::GetTryItems(code_item, try_item)->handler_off_;
663   }
664 }
665 
DecodeDebugInfo0(const CodeItem * code_item,bool is_static,uint32_t method_idx,DexDebugNewPositionCb position_cb,DexDebugNewLocalCb local_cb,void * context,const byte * stream,LocalInfo * local_in_reg) const666 void DexFile::DecodeDebugInfo0(const CodeItem* code_item, bool is_static, uint32_t method_idx,
667                                DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
668                                void* context, const byte* stream, LocalInfo* local_in_reg) const {
669   uint32_t line = DecodeUnsignedLeb128(&stream);
670   uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
671   uint16_t arg_reg = code_item->registers_size_ - code_item->ins_size_;
672   uint32_t address = 0;
673   bool need_locals = (local_cb != NULL);
674 
675   if (!is_static) {
676     if (need_locals) {
677       const char* descriptor = GetMethodDeclaringClassDescriptor(GetMethodId(method_idx));
678       local_in_reg[arg_reg].name_ = "this";
679       local_in_reg[arg_reg].descriptor_ = descriptor;
680       local_in_reg[arg_reg].signature_ = NULL;
681       local_in_reg[arg_reg].start_address_ = 0;
682       local_in_reg[arg_reg].is_live_ = true;
683     }
684     arg_reg++;
685   }
686 
687   DexFileParameterIterator it(*this, GetMethodPrototype(GetMethodId(method_idx)));
688   for (uint32_t i = 0; i < parameters_size && it.HasNext(); ++i, it.Next()) {
689     if (arg_reg >= code_item->registers_size_) {
690       LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg
691                  << " >= " << code_item->registers_size_ << ") in " << GetLocation();
692       return;
693     }
694     uint32_t id = DecodeUnsignedLeb128P1(&stream);
695     const char* descriptor = it.GetDescriptor();
696     if (need_locals && id != kDexNoIndex) {
697       const char* name = StringDataByIdx(id);
698       local_in_reg[arg_reg].name_ = name;
699       local_in_reg[arg_reg].descriptor_ = descriptor;
700       local_in_reg[arg_reg].signature_ = NULL;
701       local_in_reg[arg_reg].start_address_ = address;
702       local_in_reg[arg_reg].is_live_ = true;
703     }
704     switch (*descriptor) {
705       case 'D':
706       case 'J':
707         arg_reg += 2;
708         break;
709       default:
710         arg_reg += 1;
711         break;
712     }
713   }
714 
715   if (it.HasNext()) {
716     LOG(ERROR) << "invalid stream - problem with parameter iterator in " << GetLocation();
717     return;
718   }
719 
720   for (;;)  {
721     uint8_t opcode = *stream++;
722     uint16_t reg;
723     uint16_t name_idx;
724     uint16_t descriptor_idx;
725     uint16_t signature_idx = 0;
726 
727     switch (opcode) {
728       case DBG_END_SEQUENCE:
729         return;
730 
731       case DBG_ADVANCE_PC:
732         address += DecodeUnsignedLeb128(&stream);
733         break;
734 
735       case DBG_ADVANCE_LINE:
736         line += DecodeSignedLeb128(&stream);
737         break;
738 
739       case DBG_START_LOCAL:
740       case DBG_START_LOCAL_EXTENDED:
741         reg = DecodeUnsignedLeb128(&stream);
742         if (reg > code_item->registers_size_) {
743           LOG(ERROR) << "invalid stream - reg > reg size (" << reg << " > "
744                      << code_item->registers_size_ << ") in " << GetLocation();
745           return;
746         }
747 
748         name_idx = DecodeUnsignedLeb128P1(&stream);
749         descriptor_idx = DecodeUnsignedLeb128P1(&stream);
750         if (opcode == DBG_START_LOCAL_EXTENDED) {
751           signature_idx = DecodeUnsignedLeb128P1(&stream);
752         }
753 
754         // Emit what was previously there, if anything
755         if (need_locals) {
756           InvokeLocalCbIfLive(context, reg, address, local_in_reg, local_cb);
757 
758           local_in_reg[reg].name_ = StringDataByIdx(name_idx);
759           local_in_reg[reg].descriptor_ = StringByTypeIdx(descriptor_idx);
760           if (opcode == DBG_START_LOCAL_EXTENDED) {
761             local_in_reg[reg].signature_ = StringDataByIdx(signature_idx);
762           }
763           local_in_reg[reg].start_address_ = address;
764           local_in_reg[reg].is_live_ = true;
765         }
766         break;
767 
768       case DBG_END_LOCAL:
769         reg = DecodeUnsignedLeb128(&stream);
770         if (reg > code_item->registers_size_) {
771           LOG(ERROR) << "invalid stream - reg > reg size (" << reg << " > "
772                      << code_item->registers_size_ << ") in " << GetLocation();
773           return;
774         }
775 
776         if (need_locals) {
777           InvokeLocalCbIfLive(context, reg, address, local_in_reg, local_cb);
778           local_in_reg[reg].is_live_ = false;
779         }
780         break;
781 
782       case DBG_RESTART_LOCAL:
783         reg = DecodeUnsignedLeb128(&stream);
784         if (reg > code_item->registers_size_) {
785           LOG(ERROR) << "invalid stream - reg > reg size (" << reg << " > "
786                      << code_item->registers_size_ << ") in " << GetLocation();
787           return;
788         }
789 
790         if (need_locals) {
791           if (local_in_reg[reg].name_ == NULL || local_in_reg[reg].descriptor_ == NULL) {
792             LOG(ERROR) << "invalid stream - no name or descriptor in " << GetLocation();
793             return;
794           }
795 
796           // If the register is live, the "restart" is superfluous,
797           // and we don't want to mess with the existing start address.
798           if (!local_in_reg[reg].is_live_) {
799             local_in_reg[reg].start_address_ = address;
800             local_in_reg[reg].is_live_ = true;
801           }
802         }
803         break;
804 
805       case DBG_SET_PROLOGUE_END:
806       case DBG_SET_EPILOGUE_BEGIN:
807       case DBG_SET_FILE:
808         break;
809 
810       default: {
811         int adjopcode = opcode - DBG_FIRST_SPECIAL;
812 
813         address += adjopcode / DBG_LINE_RANGE;
814         line += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);
815 
816         if (position_cb != NULL) {
817           if (position_cb(context, address, line)) {
818             // early exit
819             return;
820           }
821         }
822         break;
823       }
824     }
825   }
826 }
827 
DecodeDebugInfo(const CodeItem * code_item,bool is_static,uint32_t method_idx,DexDebugNewPositionCb position_cb,DexDebugNewLocalCb local_cb,void * context) const828 void DexFile::DecodeDebugInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx,
829                               DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
830                               void* context) const {
831   const byte* stream = GetDebugInfoStream(code_item);
832   UniquePtr<LocalInfo[]> local_in_reg(local_cb != NULL ?
833                                       new LocalInfo[code_item->registers_size_] :
834                                       NULL);
835   if (stream != NULL) {
836     DecodeDebugInfo0(code_item, is_static, method_idx, position_cb, local_cb, context, stream, &local_in_reg[0]);
837   }
838   for (int reg = 0; reg < code_item->registers_size_; reg++) {
839     InvokeLocalCbIfLive(context, reg, code_item->insns_size_in_code_units_, &local_in_reg[0], local_cb);
840   }
841 }
842 
LineNumForPcCb(void * raw_context,uint32_t address,uint32_t line_num)843 bool DexFile::LineNumForPcCb(void* raw_context, uint32_t address, uint32_t line_num) {
844   LineNumFromPcContext* context = reinterpret_cast<LineNumFromPcContext*>(raw_context);
845 
846   // We know that this callback will be called in
847   // ascending address order, so keep going until we find
848   // a match or we've just gone past it.
849   if (address > context->address_) {
850     // The line number from the previous positions callback
851     // wil be the final result.
852     return true;
853   } else {
854     context->line_num_ = line_num;
855     return address == context->address_;
856   }
857 }
858 
859 // Decodes the header section from the class data bytes.
ReadClassDataHeader()860 void ClassDataItemIterator::ReadClassDataHeader() {
861   CHECK(ptr_pos_ != NULL);
862   header_.static_fields_size_ = DecodeUnsignedLeb128(&ptr_pos_);
863   header_.instance_fields_size_ = DecodeUnsignedLeb128(&ptr_pos_);
864   header_.direct_methods_size_ = DecodeUnsignedLeb128(&ptr_pos_);
865   header_.virtual_methods_size_ = DecodeUnsignedLeb128(&ptr_pos_);
866 }
867 
ReadClassDataField()868 void ClassDataItemIterator::ReadClassDataField() {
869   field_.field_idx_delta_ = DecodeUnsignedLeb128(&ptr_pos_);
870   field_.access_flags_ = DecodeUnsignedLeb128(&ptr_pos_);
871   if (last_idx_ != 0 && field_.field_idx_delta_ == 0) {
872     LOG(WARNING) << "Duplicate field " << PrettyField(GetMemberIndex(), dex_file_)
873                  << " in " << dex_file_.GetLocation();
874   }
875 }
876 
ReadClassDataMethod()877 void ClassDataItemIterator::ReadClassDataMethod() {
878   method_.method_idx_delta_ = DecodeUnsignedLeb128(&ptr_pos_);
879   method_.access_flags_ = DecodeUnsignedLeb128(&ptr_pos_);
880   method_.code_off_ = DecodeUnsignedLeb128(&ptr_pos_);
881   if (last_idx_ != 0 && method_.method_idx_delta_ == 0) {
882     LOG(WARNING) << "Duplicate method " << PrettyMethod(GetMemberIndex(), dex_file_)
883                  << " in " << dex_file_.GetLocation();
884   }
885 }
886 
887 // Read a signed integer.  "zwidth" is the zero-based byte count.
ReadSignedInt(const byte * ptr,int zwidth)888 static int32_t ReadSignedInt(const byte* ptr, int zwidth) {
889   int32_t val = 0;
890   for (int i = zwidth; i >= 0; --i) {
891     val = ((uint32_t)val >> 8) | (((int32_t)*ptr++) << 24);
892   }
893   val >>= (3 - zwidth) * 8;
894   return val;
895 }
896 
897 // Read an unsigned integer.  "zwidth" is the zero-based byte count,
898 // "fill_on_right" indicates which side we want to zero-fill from.
ReadUnsignedInt(const byte * ptr,int zwidth,bool fill_on_right)899 static uint32_t ReadUnsignedInt(const byte* ptr, int zwidth, bool fill_on_right) {
900   uint32_t val = 0;
901   if (!fill_on_right) {
902     for (int i = zwidth; i >= 0; --i) {
903       val = (val >> 8) | (((uint32_t)*ptr++) << 24);
904     }
905     val >>= (3 - zwidth) * 8;
906   } else {
907     for (int i = zwidth; i >= 0; --i) {
908       val = (val >> 8) | (((uint32_t)*ptr++) << 24);
909     }
910   }
911   return val;
912 }
913 
914 // Read a signed long.  "zwidth" is the zero-based byte count.
ReadSignedLong(const byte * ptr,int zwidth)915 static int64_t ReadSignedLong(const byte* ptr, int zwidth) {
916   int64_t val = 0;
917   for (int i = zwidth; i >= 0; --i) {
918     val = ((uint64_t)val >> 8) | (((int64_t)*ptr++) << 56);
919   }
920   val >>= (7 - zwidth) * 8;
921   return val;
922 }
923 
924 // Read an unsigned long.  "zwidth" is the zero-based byte count,
925 // "fill_on_right" indicates which side we want to zero-fill from.
ReadUnsignedLong(const byte * ptr,int zwidth,bool fill_on_right)926 static uint64_t ReadUnsignedLong(const byte* ptr, int zwidth, bool fill_on_right) {
927   uint64_t val = 0;
928   if (!fill_on_right) {
929     for (int i = zwidth; i >= 0; --i) {
930       val = (val >> 8) | (((uint64_t)*ptr++) << 56);
931     }
932     val >>= (7 - zwidth) * 8;
933   } else {
934     for (int i = zwidth; i >= 0; --i) {
935       val = (val >> 8) | (((uint64_t)*ptr++) << 56);
936     }
937   }
938   return val;
939 }
940 
EncodedStaticFieldValueIterator(const DexFile & dex_file,mirror::DexCache * dex_cache,mirror::ClassLoader * class_loader,ClassLinker * linker,const DexFile::ClassDef & class_def)941 EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator(const DexFile& dex_file,
942                                                                  mirror::DexCache* dex_cache,
943                                                                  mirror::ClassLoader* class_loader,
944                                                                  ClassLinker* linker,
945                                                                  const DexFile::ClassDef& class_def)
946     : dex_file_(dex_file), dex_cache_(dex_cache), class_loader_(class_loader), linker_(linker),
947       array_size_(), pos_(-1), type_(kByte) {
948   ptr_ = dex_file.GetEncodedStaticFieldValuesArray(class_def);
949   if (ptr_ == NULL) {
950     array_size_ = 0;
951   } else {
952     array_size_ = DecodeUnsignedLeb128(&ptr_);
953   }
954   if (array_size_ > 0) {
955     Next();
956   }
957 }
958 
Next()959 void EncodedStaticFieldValueIterator::Next() {
960   pos_++;
961   if (pos_ >= array_size_) {
962     return;
963   }
964   byte value_type = *ptr_++;
965   byte value_arg = value_type >> kEncodedValueArgShift;
966   size_t width = value_arg + 1;  // assume and correct later
967   type_ = static_cast<ValueType>(value_type & kEncodedValueTypeMask);
968   switch (type_) {
969   case kBoolean:
970     jval_.i = (value_arg != 0) ? 1 : 0;
971     width = 0;
972     break;
973   case kByte:
974     jval_.i = ReadSignedInt(ptr_, value_arg);
975     CHECK(IsInt(8, jval_.i));
976     break;
977   case kShort:
978     jval_.i = ReadSignedInt(ptr_, value_arg);
979     CHECK(IsInt(16, jval_.i));
980     break;
981   case kChar:
982     jval_.i = ReadUnsignedInt(ptr_, value_arg, false);
983     CHECK(IsUint(16, jval_.i));
984     break;
985   case kInt:
986     jval_.i = ReadSignedInt(ptr_, value_arg);
987     break;
988   case kLong:
989     jval_.j = ReadSignedLong(ptr_, value_arg);
990     break;
991   case kFloat:
992     jval_.i = ReadUnsignedInt(ptr_, value_arg, true);
993     break;
994   case kDouble:
995     jval_.j = ReadUnsignedLong(ptr_, value_arg, true);
996     break;
997   case kString:
998   case kType:
999     jval_.i = ReadUnsignedInt(ptr_, value_arg, false);
1000     break;
1001   case kField:
1002   case kMethod:
1003   case kEnum:
1004   case kArray:
1005   case kAnnotation:
1006     UNIMPLEMENTED(FATAL) << ": type " << type_;
1007     break;
1008   case kNull:
1009     jval_.l = NULL;
1010     width = 0;
1011     break;
1012   default:
1013     LOG(FATAL) << "Unreached";
1014   }
1015   ptr_ += width;
1016 }
1017 
ReadValueToField(mirror::ArtField * field) const1018 void EncodedStaticFieldValueIterator::ReadValueToField(mirror::ArtField* field) const {
1019   switch (type_) {
1020     case kBoolean: field->SetBoolean(field->GetDeclaringClass(), jval_.z); break;
1021     case kByte:    field->SetByte(field->GetDeclaringClass(), jval_.b); break;
1022     case kShort:   field->SetShort(field->GetDeclaringClass(), jval_.s); break;
1023     case kChar:    field->SetChar(field->GetDeclaringClass(), jval_.c); break;
1024     case kInt:     field->SetInt(field->GetDeclaringClass(), jval_.i); break;
1025     case kLong:    field->SetLong(field->GetDeclaringClass(), jval_.j); break;
1026     case kFloat:   field->SetFloat(field->GetDeclaringClass(), jval_.f); break;
1027     case kDouble:  field->SetDouble(field->GetDeclaringClass(), jval_.d); break;
1028     case kNull:    field->SetObject(field->GetDeclaringClass(), NULL); break;
1029     case kString: {
1030       mirror::String* resolved = linker_->ResolveString(dex_file_, jval_.i, dex_cache_);
1031       field->SetObject(field->GetDeclaringClass(), resolved);
1032       break;
1033     }
1034     case kType: {
1035       mirror::Class* resolved = linker_->ResolveType(dex_file_, jval_.i, dex_cache_, class_loader_);
1036       field->SetObject(field->GetDeclaringClass(), resolved);
1037       break;
1038     }
1039     default: UNIMPLEMENTED(FATAL) << ": type " << type_;
1040   }
1041 }
1042 
CatchHandlerIterator(const DexFile::CodeItem & code_item,uint32_t address)1043 CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address) {
1044   handler_.address_ = -1;
1045   int32_t offset = -1;
1046 
1047   // Short-circuit the overwhelmingly common cases.
1048   switch (code_item.tries_size_) {
1049     case 0:
1050       break;
1051     case 1: {
1052       const DexFile::TryItem* tries = DexFile::GetTryItems(code_item, 0);
1053       uint32_t start = tries->start_addr_;
1054       if (address >= start) {
1055         uint32_t end = start + tries->insn_count_;
1056         if (address < end) {
1057           offset = tries->handler_off_;
1058         }
1059       }
1060       break;
1061     }
1062     default:
1063       offset = DexFile::FindCatchHandlerOffset(code_item, address);
1064   }
1065   Init(code_item, offset);
1066 }
1067 
CatchHandlerIterator(const DexFile::CodeItem & code_item,const DexFile::TryItem & try_item)1068 CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item,
1069                                            const DexFile::TryItem& try_item) {
1070   handler_.address_ = -1;
1071   Init(code_item, try_item.handler_off_);
1072 }
1073 
Init(const DexFile::CodeItem & code_item,int32_t offset)1074 void CatchHandlerIterator::Init(const DexFile::CodeItem& code_item,
1075                                 int32_t offset) {
1076   if (offset >= 0) {
1077     Init(DexFile::GetCatchHandlerData(code_item, offset));
1078   } else {
1079     // Not found, initialize as empty
1080     current_data_ = NULL;
1081     remaining_count_ = -1;
1082     catch_all_ = false;
1083     DCHECK(!HasNext());
1084   }
1085 }
1086 
Init(const byte * handler_data)1087 void CatchHandlerIterator::Init(const byte* handler_data) {
1088   current_data_ = handler_data;
1089   remaining_count_ = DecodeSignedLeb128(&current_data_);
1090 
1091   // If remaining_count_ is non-positive, then it is the negative of
1092   // the number of catch types, and the catches are followed by a
1093   // catch-all handler.
1094   if (remaining_count_ <= 0) {
1095     catch_all_ = true;
1096     remaining_count_ = -remaining_count_;
1097   } else {
1098     catch_all_ = false;
1099   }
1100   Next();
1101 }
1102 
Next()1103 void CatchHandlerIterator::Next() {
1104   if (remaining_count_ > 0) {
1105     handler_.type_idx_ = DecodeUnsignedLeb128(&current_data_);
1106     handler_.address_  = DecodeUnsignedLeb128(&current_data_);
1107     remaining_count_--;
1108     return;
1109   }
1110 
1111   if (catch_all_) {
1112     handler_.type_idx_ = DexFile::kDexNoIndex16;
1113     handler_.address_  = DecodeUnsignedLeb128(&current_data_);
1114     catch_all_ = false;
1115     return;
1116   }
1117 
1118   // no more handler
1119   remaining_count_ = -1;
1120 }
1121 
1122 }  // namespace art
1123