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 #include <memory>
27 
28 #include "base/logging.h"
29 #include "base/stringprintf.h"
30 #include "class_linker.h"
31 #include "dex_file-inl.h"
32 #include "dex_file_verifier.h"
33 #include "globals.h"
34 #include "leb128.h"
35 #include "mirror/art_field-inl.h"
36 #include "mirror/art_method-inl.h"
37 #include "mirror/string.h"
38 #include "os.h"
39 #include "safe_map.h"
40 #include "ScopedFd.h"
41 #include "handle_scope-inl.h"
42 #include "thread.h"
43 #include "utf-inl.h"
44 #include "utils.h"
45 #include "well_known_classes.h"
46 #include "zip_archive.h"
47 
48 namespace art {
49 
50 const byte DexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
51 const byte DexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' };
52 
OpenAndReadMagic(const char * filename,uint32_t * magic,std::string * error_msg)53 static int OpenAndReadMagic(const char* filename, uint32_t* magic, std::string* error_msg) {
54   CHECK(magic != NULL);
55   ScopedFd fd(open(filename, O_RDONLY, 0));
56   if (fd.get() == -1) {
57     *error_msg = StringPrintf("Unable to open '%s' : %s", filename, strerror(errno));
58     return -1;
59   }
60   int n = TEMP_FAILURE_RETRY(read(fd.get(), magic, sizeof(*magic)));
61   if (n != sizeof(*magic)) {
62     *error_msg = StringPrintf("Failed to find magic in '%s'", filename);
63     return -1;
64   }
65   if (lseek(fd.get(), 0, SEEK_SET) != 0) {
66     *error_msg = StringPrintf("Failed to seek to beginning of file '%s' : %s", filename,
67                               strerror(errno));
68     return -1;
69   }
70   return fd.release();
71 }
72 
GetChecksum(const char * filename,uint32_t * checksum,std::string * error_msg)73 bool DexFile::GetChecksum(const char* filename, uint32_t* checksum, std::string* error_msg) {
74   CHECK(checksum != NULL);
75   uint32_t magic;
76 
77   // Strip ":...", which is the location
78   const char* zip_entry_name = kClassesDex;
79   const char* file_part = filename;
80   std::string file_part_storage;
81 
82   if (DexFile::IsMultiDexLocation(filename)) {
83     file_part_storage = GetBaseLocation(filename);
84     file_part = file_part_storage.c_str();
85     zip_entry_name = filename + file_part_storage.size() + 1;
86     DCHECK_EQ(zip_entry_name[-1], kMultiDexSeparator);
87   }
88 
89   ScopedFd fd(OpenAndReadMagic(file_part, &magic, error_msg));
90   if (fd.get() == -1) {
91     DCHECK(!error_msg->empty());
92     return false;
93   }
94   if (IsZipMagic(magic)) {
95     std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(fd.release(), filename, error_msg));
96     if (zip_archive.get() == NULL) {
97       *error_msg = StringPrintf("Failed to open zip archive '%s'", file_part);
98       return false;
99     }
100     std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(zip_entry_name, error_msg));
101     if (zip_entry.get() == NULL) {
102       *error_msg = StringPrintf("Zip archive '%s' doesn't contain %s (error msg: %s)", file_part,
103                                 zip_entry_name, error_msg->c_str());
104       return false;
105     }
106     *checksum = zip_entry->GetCrc32();
107     return true;
108   }
109   if (IsDexMagic(magic)) {
110     std::unique_ptr<const DexFile> dex_file(DexFile::OpenFile(fd.release(), filename, false, error_msg));
111     if (dex_file.get() == NULL) {
112       return false;
113     }
114     *checksum = dex_file->GetHeader().checksum_;
115     return true;
116   }
117   *error_msg = StringPrintf("Expected valid zip or dex file: '%s'", filename);
118   return false;
119 }
120 
Open(const char * filename,const char * location,std::string * error_msg,std::vector<const DexFile * > * dex_files)121 bool DexFile::Open(const char* filename, const char* location, std::string* error_msg,
122                    std::vector<const DexFile*>* dex_files) {
123   uint32_t magic;
124   ScopedFd fd(OpenAndReadMagic(filename, &magic, error_msg));
125   if (fd.get() == -1) {
126     DCHECK(!error_msg->empty());
127     return false;
128   }
129   if (IsZipMagic(magic)) {
130     return DexFile::OpenZip(fd.release(), location, error_msg, dex_files);
131   }
132   if (IsDexMagic(magic)) {
133     std::unique_ptr<const DexFile> dex_file(DexFile::OpenFile(fd.release(), location, true,
134                                                               error_msg));
135     if (dex_file.get() != nullptr) {
136       dex_files->push_back(dex_file.release());
137       return true;
138     } else {
139       return false;
140     }
141   }
142   *error_msg = StringPrintf("Expected valid zip or dex file: '%s'", filename);
143   return false;
144 }
145 
GetPermissions() const146 int DexFile::GetPermissions() const {
147   if (mem_map_.get() == NULL) {
148     return 0;
149   } else {
150     return mem_map_->GetProtect();
151   }
152 }
153 
IsReadOnly() const154 bool DexFile::IsReadOnly() const {
155   return GetPermissions() == PROT_READ;
156 }
157 
EnableWrite() const158 bool DexFile::EnableWrite() const {
159   CHECK(IsReadOnly());
160   if (mem_map_.get() == NULL) {
161     return false;
162   } else {
163     return mem_map_->Protect(PROT_READ | PROT_WRITE);
164   }
165 }
166 
DisableWrite() const167 bool DexFile::DisableWrite() const {
168   CHECK(!IsReadOnly());
169   if (mem_map_.get() == NULL) {
170     return false;
171   } else {
172     return mem_map_->Protect(PROT_READ);
173   }
174 }
175 
OpenFile(int fd,const char * location,bool verify,std::string * error_msg)176 const DexFile* DexFile::OpenFile(int fd, const char* location, bool verify,
177                                  std::string* error_msg) {
178   CHECK(location != nullptr);
179   std::unique_ptr<MemMap> map;
180   {
181     ScopedFd delayed_close(fd);
182     struct stat sbuf;
183     memset(&sbuf, 0, sizeof(sbuf));
184     if (fstat(fd, &sbuf) == -1) {
185       *error_msg = StringPrintf("DexFile: fstat '%s' failed: %s", location, strerror(errno));
186       return nullptr;
187     }
188     if (S_ISDIR(sbuf.st_mode)) {
189       *error_msg = StringPrintf("Attempt to mmap directory '%s'", location);
190       return nullptr;
191     }
192     size_t length = sbuf.st_size;
193     map.reset(MemMap::MapFile(length, PROT_READ, MAP_PRIVATE, fd, 0, location, error_msg));
194     if (map.get() == nullptr) {
195       DCHECK(!error_msg->empty());
196       return nullptr;
197     }
198   }
199 
200   if (map->Size() < sizeof(DexFile::Header)) {
201     *error_msg = StringPrintf(
202         "DexFile: failed to open dex file '%s' that is too short to have a header", location);
203     return nullptr;
204   }
205 
206   const Header* dex_header = reinterpret_cast<const Header*>(map->Begin());
207 
208   const DexFile* dex_file = OpenMemory(location, dex_header->checksum_, map.release(), error_msg);
209   if (dex_file == nullptr) {
210     *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location,
211                               error_msg->c_str());
212     return nullptr;
213   }
214 
215   if (verify && !DexFileVerifier::Verify(dex_file, dex_file->Begin(), dex_file->Size(), location,
216                                          error_msg)) {
217     return nullptr;
218   }
219 
220   return dex_file;
221 }
222 
223 const char* DexFile::kClassesDex = "classes.dex";
224 
OpenZip(int fd,const std::string & location,std::string * error_msg,std::vector<const DexFile * > * dex_files)225 bool DexFile::OpenZip(int fd, const std::string& location, std::string* error_msg,
226                       std::vector<const  DexFile*>* dex_files) {
227   std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(fd, location.c_str(), error_msg));
228   if (zip_archive.get() == nullptr) {
229     DCHECK(!error_msg->empty());
230     return false;
231   }
232   return DexFile::OpenFromZip(*zip_archive, location, error_msg, dex_files);
233 }
234 
OpenMemory(const std::string & location,uint32_t location_checksum,MemMap * mem_map,std::string * error_msg)235 const DexFile* DexFile::OpenMemory(const std::string& location,
236                                    uint32_t location_checksum,
237                                    MemMap* mem_map,
238                                    std::string* error_msg) {
239   return OpenMemory(mem_map->Begin(),
240                     mem_map->Size(),
241                     location,
242                     location_checksum,
243                     mem_map,
244                     nullptr,
245                     error_msg);
246 }
247 
Open(const ZipArchive & zip_archive,const char * entry_name,const std::string & location,std::string * error_msg,ZipOpenErrorCode * error_code)248 const DexFile* DexFile::Open(const ZipArchive& zip_archive, const char* entry_name,
249                              const std::string& location, std::string* error_msg,
250                              ZipOpenErrorCode* error_code) {
251   CHECK(!location.empty());
252   std::unique_ptr<ZipEntry> zip_entry(zip_archive.Find(entry_name, error_msg));
253   if (zip_entry.get() == NULL) {
254     *error_code = ZipOpenErrorCode::kEntryNotFound;
255     return nullptr;
256   }
257   std::unique_ptr<MemMap> map(zip_entry->ExtractToMemMap(location.c_str(), entry_name, error_msg));
258   if (map.get() == NULL) {
259     *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", entry_name, location.c_str(),
260                               error_msg->c_str());
261     *error_code = ZipOpenErrorCode::kExtractToMemoryError;
262     return nullptr;
263   }
264   std::unique_ptr<const DexFile> dex_file(OpenMemory(location, zip_entry->GetCrc32(), map.release(),
265                                                error_msg));
266   if (dex_file.get() == nullptr) {
267     *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location.c_str(),
268                               error_msg->c_str());
269     *error_code = ZipOpenErrorCode::kDexFileError;
270     return nullptr;
271   }
272   if (!dex_file->DisableWrite()) {
273     *error_msg = StringPrintf("Failed to make dex file '%s' read only", location.c_str());
274     *error_code = ZipOpenErrorCode::kMakeReadOnlyError;
275     return nullptr;
276   }
277   CHECK(dex_file->IsReadOnly()) << location;
278   if (!DexFileVerifier::Verify(dex_file.get(), dex_file->Begin(), dex_file->Size(),
279                                location.c_str(), error_msg)) {
280     *error_code = ZipOpenErrorCode::kVerifyError;
281     return nullptr;
282   }
283   *error_code = ZipOpenErrorCode::kNoError;
284   return dex_file.release();
285 }
286 
OpenFromZip(const ZipArchive & zip_archive,const std::string & location,std::string * error_msg,std::vector<const DexFile * > * dex_files)287 bool DexFile::OpenFromZip(const ZipArchive& zip_archive, const std::string& location,
288                           std::string* error_msg, std::vector<const DexFile*>* dex_files) {
289   ZipOpenErrorCode error_code;
290   std::unique_ptr<const DexFile> dex_file(Open(zip_archive, kClassesDex, location, error_msg,
291                                                &error_code));
292   if (dex_file.get() == nullptr) {
293     return false;
294   } else {
295     // Had at least classes.dex.
296     dex_files->push_back(dex_file.release());
297 
298     // Now try some more.
299     size_t i = 2;
300 
301     // We could try to avoid std::string allocations by working on a char array directly. As we
302     // do not expect a lot of iterations, this seems too involved and brittle.
303 
304     while (i < 100) {
305       std::string name = StringPrintf("classes%zu.dex", i);
306       std::string fake_location = location + kMultiDexSeparator + name;
307       std::unique_ptr<const DexFile> next_dex_file(Open(zip_archive, name.c_str(), fake_location,
308                                                         error_msg, &error_code));
309       if (next_dex_file.get() == nullptr) {
310         if (error_code != ZipOpenErrorCode::kEntryNotFound) {
311           LOG(WARNING) << error_msg;
312         }
313         break;
314       } else {
315         dex_files->push_back(next_dex_file.release());
316       }
317 
318       i++;
319     }
320 
321     return true;
322   }
323 }
324 
325 
OpenMemory(const byte * base,size_t size,const std::string & location,uint32_t location_checksum,MemMap * mem_map,const OatFile * oat_file,std::string * error_msg)326 const DexFile* DexFile::OpenMemory(const byte* base,
327                                    size_t size,
328                                    const std::string& location,
329                                    uint32_t location_checksum,
330                                    MemMap* mem_map,
331                                    const OatFile* oat_file,
332                                    std::string* error_msg) {
333   CHECK_ALIGNED(base, 4);  // various dex file structures must be word aligned
334   std::unique_ptr<DexFile> dex_file(
335       new DexFile(base, size, location, location_checksum, mem_map, oat_file));
336   if (!dex_file->Init(error_msg)) {
337     return nullptr;
338   } else {
339     return dex_file.release();
340   }
341 }
342 
DexFile(const byte * base,size_t size,const std::string & location,uint32_t location_checksum,MemMap * mem_map,const OatFile * oat_file)343 DexFile::DexFile(const byte* base, size_t size,
344                  const std::string& location,
345                  uint32_t location_checksum,
346                  MemMap* mem_map,
347                  const OatFile* oat_file)
348     : begin_(base),
349       size_(size),
350       location_(location),
351       location_checksum_(location_checksum),
352       mem_map_(mem_map),
353       header_(reinterpret_cast<const Header*>(base)),
354       string_ids_(reinterpret_cast<const StringId*>(base + header_->string_ids_off_)),
355       type_ids_(reinterpret_cast<const TypeId*>(base + header_->type_ids_off_)),
356       field_ids_(reinterpret_cast<const FieldId*>(base + header_->field_ids_off_)),
357       method_ids_(reinterpret_cast<const MethodId*>(base + header_->method_ids_off_)),
358       proto_ids_(reinterpret_cast<const ProtoId*>(base + header_->proto_ids_off_)),
359       class_defs_(reinterpret_cast<const ClassDef*>(base + header_->class_defs_off_)),
360       find_class_def_misses_(0),
361       class_def_index_(nullptr),
362       build_class_def_index_mutex_("DexFile index creation mutex"),
363       oat_file_(oat_file) {
364   CHECK(begin_ != NULL) << GetLocation();
365   CHECK_GT(size_, 0U) << GetLocation();
366 }
367 
~DexFile()368 DexFile::~DexFile() {
369   // We don't call DeleteGlobalRef on dex_object_ because we're only called by DestroyJavaVM, and
370   // that's only called after DetachCurrentThread, which means there's no JNIEnv. We could
371   // re-attach, but cleaning up these global references is not obviously useful. It's not as if
372   // the global reference table is otherwise empty!
373   // Remove the index if one were created.
374   delete class_def_index_.LoadRelaxed();
375 }
376 
Init(std::string * error_msg)377 bool DexFile::Init(std::string* error_msg) {
378   if (!CheckMagicAndVersion(error_msg)) {
379     return false;
380   }
381   return true;
382 }
383 
CheckMagicAndVersion(std::string * error_msg) const384 bool DexFile::CheckMagicAndVersion(std::string* error_msg) const {
385   if (!IsMagicValid(header_->magic_)) {
386     std::ostringstream oss;
387     oss << "Unrecognized magic number in "  << GetLocation() << ":"
388             << " " << header_->magic_[0]
389             << " " << header_->magic_[1]
390             << " " << header_->magic_[2]
391             << " " << header_->magic_[3];
392     *error_msg = oss.str();
393     return false;
394   }
395   if (!IsVersionValid(header_->magic_)) {
396     std::ostringstream oss;
397     oss << "Unrecognized version number in "  << GetLocation() << ":"
398             << " " << header_->magic_[4]
399             << " " << header_->magic_[5]
400             << " " << header_->magic_[6]
401             << " " << header_->magic_[7];
402     *error_msg = oss.str();
403     return false;
404   }
405   return true;
406 }
407 
IsMagicValid(const byte * magic)408 bool DexFile::IsMagicValid(const byte* magic) {
409   return (memcmp(magic, kDexMagic, sizeof(kDexMagic)) == 0);
410 }
411 
IsVersionValid(const byte * magic)412 bool DexFile::IsVersionValid(const byte* magic) {
413   const byte* version = &magic[sizeof(kDexMagic)];
414   return (memcmp(version, kDexMagicVersion, sizeof(kDexMagicVersion)) == 0);
415 }
416 
GetVersion() const417 uint32_t DexFile::GetVersion() const {
418   const char* version = reinterpret_cast<const char*>(&GetHeader().magic_[sizeof(kDexMagic)]);
419   return atoi(version);
420 }
421 
FindClassDef(const char * descriptor,size_t hash) const422 const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor, size_t hash) const {
423   DCHECK_EQ(ComputeModifiedUtf8Hash(descriptor), hash);
424   // If we have an index lookup the descriptor via that as its constant time to search.
425   Index* index = class_def_index_.LoadSequentiallyConsistent();
426   if (index != nullptr) {
427     auto it = index->FindWithHash(descriptor, hash);
428     return (it == index->end()) ? nullptr : it->second;
429   }
430   // Fast path for rate no class defs case.
431   uint32_t num_class_defs = NumClassDefs();
432   if (num_class_defs == 0) {
433     return nullptr;
434   }
435   // Search for class def with 2 binary searches and then a linear search.
436   const StringId* string_id = FindStringId(descriptor);
437   if (string_id != nullptr) {
438     const TypeId* type_id = FindTypeId(GetIndexForStringId(*string_id));
439     if (type_id != nullptr) {
440       uint16_t type_idx = GetIndexForTypeId(*type_id);
441       for (size_t i = 0; i < num_class_defs; ++i) {
442         const ClassDef& class_def = GetClassDef(i);
443         if (class_def.class_idx_ == type_idx) {
444           return &class_def;
445         }
446       }
447     }
448   }
449   // A miss. If we've had kMaxFailedDexClassDefLookups misses then build an index to speed things
450   // up. This isn't done eagerly at construction as construction is not performed in multi-threaded
451   // sections of tools like dex2oat. If we're lazy we hopefully increase the chance of balancing
452   // out which thread builds the index.
453   find_class_def_misses_++;
454   const uint32_t kMaxFailedDexClassDefLookups = 100;
455   if (find_class_def_misses_ > kMaxFailedDexClassDefLookups) {
456     MutexLock mu(Thread::Current(), build_class_def_index_mutex_);
457     // Are we the first ones building the index?
458     if (class_def_index_.LoadSequentiallyConsistent() == nullptr) {
459       index = new Index;
460       for (uint32_t i = 0; i < num_class_defs;  ++i) {
461         const ClassDef& class_def = GetClassDef(i);
462         const char* descriptor = GetClassDescriptor(class_def);
463         index->Insert(std::make_pair(descriptor, &class_def));
464       }
465       class_def_index_.StoreSequentiallyConsistent(index);
466     }
467   }
468   return nullptr;
469 }
470 
FindClassDef(uint16_t type_idx) const471 const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const {
472   size_t num_class_defs = NumClassDefs();
473   for (size_t i = 0; i < num_class_defs; ++i) {
474     const ClassDef& class_def = GetClassDef(i);
475     if (class_def.class_idx_ == type_idx) {
476       return &class_def;
477     }
478   }
479   return NULL;
480 }
481 
FindFieldId(const DexFile::TypeId & declaring_klass,const DexFile::StringId & name,const DexFile::TypeId & type) const482 const DexFile::FieldId* DexFile::FindFieldId(const DexFile::TypeId& declaring_klass,
483                                               const DexFile::StringId& name,
484                                               const DexFile::TypeId& type) const {
485   // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx
486   const uint16_t class_idx = GetIndexForTypeId(declaring_klass);
487   const uint32_t name_idx = GetIndexForStringId(name);
488   const uint16_t type_idx = GetIndexForTypeId(type);
489   int32_t lo = 0;
490   int32_t hi = NumFieldIds() - 1;
491   while (hi >= lo) {
492     int32_t mid = (hi + lo) / 2;
493     const DexFile::FieldId& field = GetFieldId(mid);
494     if (class_idx > field.class_idx_) {
495       lo = mid + 1;
496     } else if (class_idx < field.class_idx_) {
497       hi = mid - 1;
498     } else {
499       if (name_idx > field.name_idx_) {
500         lo = mid + 1;
501       } else if (name_idx < field.name_idx_) {
502         hi = mid - 1;
503       } else {
504         if (type_idx > field.type_idx_) {
505           lo = mid + 1;
506         } else if (type_idx < field.type_idx_) {
507           hi = mid - 1;
508         } else {
509           return &field;
510         }
511       }
512     }
513   }
514   return NULL;
515 }
516 
FindMethodId(const DexFile::TypeId & declaring_klass,const DexFile::StringId & name,const DexFile::ProtoId & signature) const517 const DexFile::MethodId* DexFile::FindMethodId(const DexFile::TypeId& declaring_klass,
518                                                const DexFile::StringId& name,
519                                                const DexFile::ProtoId& signature) const {
520   // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx
521   const uint16_t class_idx = GetIndexForTypeId(declaring_klass);
522   const uint32_t name_idx = GetIndexForStringId(name);
523   const uint16_t proto_idx = GetIndexForProtoId(signature);
524   int32_t lo = 0;
525   int32_t hi = NumMethodIds() - 1;
526   while (hi >= lo) {
527     int32_t mid = (hi + lo) / 2;
528     const DexFile::MethodId& method = GetMethodId(mid);
529     if (class_idx > method.class_idx_) {
530       lo = mid + 1;
531     } else if (class_idx < method.class_idx_) {
532       hi = mid - 1;
533     } else {
534       if (name_idx > method.name_idx_) {
535         lo = mid + 1;
536       } else if (name_idx < method.name_idx_) {
537         hi = mid - 1;
538       } else {
539         if (proto_idx > method.proto_idx_) {
540           lo = mid + 1;
541         } else if (proto_idx < method.proto_idx_) {
542           hi = mid - 1;
543         } else {
544           return &method;
545         }
546       }
547     }
548   }
549   return NULL;
550 }
551 
FindStringId(const char * string) const552 const DexFile::StringId* DexFile::FindStringId(const char* string) const {
553   int32_t lo = 0;
554   int32_t hi = NumStringIds() - 1;
555   while (hi >= lo) {
556     int32_t mid = (hi + lo) / 2;
557     const DexFile::StringId& str_id = GetStringId(mid);
558     const char* str = GetStringData(str_id);
559     int compare = CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(string, str);
560     if (compare > 0) {
561       lo = mid + 1;
562     } else if (compare < 0) {
563       hi = mid - 1;
564     } else {
565       return &str_id;
566     }
567   }
568   return NULL;
569 }
570 
FindStringId(const uint16_t * string) const571 const DexFile::StringId* DexFile::FindStringId(const uint16_t* string) const {
572   int32_t lo = 0;
573   int32_t hi = NumStringIds() - 1;
574   while (hi >= lo) {
575     int32_t mid = (hi + lo) / 2;
576     const DexFile::StringId& str_id = GetStringId(mid);
577     const char* str = GetStringData(str_id);
578     int compare = CompareModifiedUtf8ToUtf16AsCodePointValues(str, string);
579     if (compare > 0) {
580       lo = mid + 1;
581     } else if (compare < 0) {
582       hi = mid - 1;
583     } else {
584       return &str_id;
585     }
586   }
587   return NULL;
588 }
589 
FindTypeId(uint32_t string_idx) const590 const DexFile::TypeId* DexFile::FindTypeId(uint32_t string_idx) const {
591   int32_t lo = 0;
592   int32_t hi = NumTypeIds() - 1;
593   while (hi >= lo) {
594     int32_t mid = (hi + lo) / 2;
595     const TypeId& type_id = GetTypeId(mid);
596     if (string_idx > type_id.descriptor_idx_) {
597       lo = mid + 1;
598     } else if (string_idx < type_id.descriptor_idx_) {
599       hi = mid - 1;
600     } else {
601       return &type_id;
602     }
603   }
604   return NULL;
605 }
606 
FindProtoId(uint16_t return_type_idx,const uint16_t * signature_type_idxs,uint32_t signature_length) const607 const DexFile::ProtoId* DexFile::FindProtoId(uint16_t return_type_idx,
608                                              const uint16_t* signature_type_idxs,
609                                              uint32_t signature_length) const {
610   int32_t lo = 0;
611   int32_t hi = NumProtoIds() - 1;
612   while (hi >= lo) {
613     int32_t mid = (hi + lo) / 2;
614     const DexFile::ProtoId& proto = GetProtoId(mid);
615     int compare = return_type_idx - proto.return_type_idx_;
616     if (compare == 0) {
617       DexFileParameterIterator it(*this, proto);
618       size_t i = 0;
619       while (it.HasNext() && i < signature_length && compare == 0) {
620         compare = signature_type_idxs[i] - it.GetTypeIdx();
621         it.Next();
622         i++;
623       }
624       if (compare == 0) {
625         if (it.HasNext()) {
626           compare = -1;
627         } else if (i < signature_length) {
628           compare = 1;
629         }
630       }
631     }
632     if (compare > 0) {
633       lo = mid + 1;
634     } else if (compare < 0) {
635       hi = mid - 1;
636     } else {
637       return &proto;
638     }
639   }
640   return NULL;
641 }
642 
643 // Given a signature place the type ids into the given vector
CreateTypeList(const StringPiece & signature,uint16_t * return_type_idx,std::vector<uint16_t> * param_type_idxs) const644 bool DexFile::CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx,
645                              std::vector<uint16_t>* param_type_idxs) const {
646   if (signature[0] != '(') {
647     return false;
648   }
649   size_t offset = 1;
650   size_t end = signature.size();
651   bool process_return = false;
652   while (offset < end) {
653     size_t start_offset = offset;
654     char c = signature[offset];
655     offset++;
656     if (c == ')') {
657       process_return = true;
658       continue;
659     }
660     while (c == '[') {  // process array prefix
661       if (offset >= end) {  // expect some descriptor following [
662         return false;
663       }
664       c = signature[offset];
665       offset++;
666     }
667     if (c == 'L') {  // process type descriptors
668       do {
669         if (offset >= end) {  // unexpected early termination of descriptor
670           return false;
671         }
672         c = signature[offset];
673         offset++;
674       } while (c != ';');
675     }
676     // TODO: avoid creating a std::string just to get a 0-terminated char array
677     std::string descriptor(signature.data() + start_offset, offset - start_offset);
678     const DexFile::StringId* string_id = FindStringId(descriptor.c_str());
679     if (string_id == NULL) {
680       return false;
681     }
682     const DexFile::TypeId* type_id = FindTypeId(GetIndexForStringId(*string_id));
683     if (type_id == NULL) {
684       return false;
685     }
686     uint16_t type_idx = GetIndexForTypeId(*type_id);
687     if (!process_return) {
688       param_type_idxs->push_back(type_idx);
689     } else {
690       *return_type_idx = type_idx;
691       return offset == end;  // return true if the signature had reached a sensible end
692     }
693   }
694   return false;  // failed to correctly parse return type
695 }
696 
CreateSignature(const StringPiece & signature) const697 const Signature DexFile::CreateSignature(const StringPiece& signature) const {
698   uint16_t return_type_idx;
699   std::vector<uint16_t> param_type_indices;
700   bool success = CreateTypeList(signature, &return_type_idx, &param_type_indices);
701   if (!success) {
702     return Signature::NoSignature();
703   }
704   const ProtoId* proto_id = FindProtoId(return_type_idx, param_type_indices);
705   if (proto_id == NULL) {
706     return Signature::NoSignature();
707   }
708   return Signature(this, *proto_id);
709 }
710 
GetLineNumFromPC(mirror::ArtMethod * method,uint32_t rel_pc) const711 int32_t DexFile::GetLineNumFromPC(mirror::ArtMethod* method, uint32_t rel_pc) const {
712   // For native method, lineno should be -2 to indicate it is native. Note that
713   // "line number == -2" is how libcore tells from StackTraceElement.
714   if (method->GetCodeItemOffset() == 0) {
715     return -2;
716   }
717 
718   const CodeItem* code_item = GetCodeItem(method->GetCodeItemOffset());
719   DCHECK(code_item != NULL) << PrettyMethod(method) << " " << GetLocation();
720 
721   // A method with no line number info should return -1
722   LineNumFromPcContext context(rel_pc, -1);
723   DecodeDebugInfo(code_item, method->IsStatic(), method->GetDexMethodIndex(), LineNumForPcCb,
724                   NULL, &context);
725   return context.line_num_;
726 }
727 
FindTryItem(const CodeItem & code_item,uint32_t address)728 int32_t DexFile::FindTryItem(const CodeItem &code_item, uint32_t address) {
729   // Note: Signed type is important for max and min.
730   int32_t min = 0;
731   int32_t max = code_item.tries_size_ - 1;
732 
733   while (min <= max) {
734     int32_t mid = min + ((max - min) / 2);
735 
736     const art::DexFile::TryItem* ti = GetTryItems(code_item, mid);
737     uint32_t start = ti->start_addr_;
738     uint32_t end = start + ti->insn_count_;
739 
740     if (address < start) {
741       max = mid - 1;
742     } else if (address >= end) {
743       min = mid + 1;
744     } else {  // We have a winner!
745       return mid;
746     }
747   }
748   // No match.
749   return -1;
750 }
751 
FindCatchHandlerOffset(const CodeItem & code_item,uint32_t address)752 int32_t DexFile::FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address) {
753   int32_t try_item = FindTryItem(code_item, address);
754   if (try_item == -1) {
755     return -1;
756   } else {
757     return DexFile::GetTryItems(code_item, try_item)->handler_off_;
758   }
759 }
760 
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) const761 void DexFile::DecodeDebugInfo0(const CodeItem* code_item, bool is_static, uint32_t method_idx,
762                                DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
763                                void* context, const byte* stream, LocalInfo* local_in_reg) const {
764   uint32_t line = DecodeUnsignedLeb128(&stream);
765   uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
766   uint16_t arg_reg = code_item->registers_size_ - code_item->ins_size_;
767   uint32_t address = 0;
768   bool need_locals = (local_cb != NULL);
769 
770   if (!is_static) {
771     if (need_locals) {
772       const char* descriptor = GetMethodDeclaringClassDescriptor(GetMethodId(method_idx));
773       local_in_reg[arg_reg].name_ = "this";
774       local_in_reg[arg_reg].descriptor_ = descriptor;
775       local_in_reg[arg_reg].signature_ = NULL;
776       local_in_reg[arg_reg].start_address_ = 0;
777       local_in_reg[arg_reg].is_live_ = true;
778     }
779     arg_reg++;
780   }
781 
782   DexFileParameterIterator it(*this, GetMethodPrototype(GetMethodId(method_idx)));
783   for (uint32_t i = 0; i < parameters_size && it.HasNext(); ++i, it.Next()) {
784     if (arg_reg >= code_item->registers_size_) {
785       LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg
786                  << " >= " << code_item->registers_size_ << ") in " << GetLocation();
787       return;
788     }
789     uint32_t id = DecodeUnsignedLeb128P1(&stream);
790     const char* descriptor = it.GetDescriptor();
791     if (need_locals && id != kDexNoIndex) {
792       const char* name = StringDataByIdx(id);
793       local_in_reg[arg_reg].name_ = name;
794       local_in_reg[arg_reg].descriptor_ = descriptor;
795       local_in_reg[arg_reg].signature_ = NULL;
796       local_in_reg[arg_reg].start_address_ = address;
797       local_in_reg[arg_reg].is_live_ = true;
798     }
799     switch (*descriptor) {
800       case 'D':
801       case 'J':
802         arg_reg += 2;
803         break;
804       default:
805         arg_reg += 1;
806         break;
807     }
808   }
809 
810   if (it.HasNext()) {
811     LOG(ERROR) << "invalid stream - problem with parameter iterator in " << GetLocation()
812                << " for method " << PrettyMethod(method_idx, *this);
813     return;
814   }
815 
816   for (;;)  {
817     uint8_t opcode = *stream++;
818     uint16_t reg;
819     uint32_t name_idx;
820     uint32_t descriptor_idx;
821     uint32_t signature_idx = 0;
822 
823     switch (opcode) {
824       case DBG_END_SEQUENCE:
825         return;
826 
827       case DBG_ADVANCE_PC:
828         address += DecodeUnsignedLeb128(&stream);
829         break;
830 
831       case DBG_ADVANCE_LINE:
832         line += DecodeSignedLeb128(&stream);
833         break;
834 
835       case DBG_START_LOCAL:
836       case DBG_START_LOCAL_EXTENDED:
837         reg = DecodeUnsignedLeb128(&stream);
838         if (reg > code_item->registers_size_) {
839           LOG(ERROR) << "invalid stream - reg > reg size (" << reg << " > "
840                      << code_item->registers_size_ << ") in " << GetLocation();
841           return;
842         }
843 
844         name_idx = DecodeUnsignedLeb128P1(&stream);
845         descriptor_idx = DecodeUnsignedLeb128P1(&stream);
846         if (opcode == DBG_START_LOCAL_EXTENDED) {
847           signature_idx = DecodeUnsignedLeb128P1(&stream);
848         }
849 
850         // Emit what was previously there, if anything
851         if (need_locals) {
852           InvokeLocalCbIfLive(context, reg, address, local_in_reg, local_cb);
853 
854           local_in_reg[reg].name_ = StringDataByIdx(name_idx);
855           local_in_reg[reg].descriptor_ = StringByTypeIdx(descriptor_idx);
856           if (opcode == DBG_START_LOCAL_EXTENDED) {
857             local_in_reg[reg].signature_ = StringDataByIdx(signature_idx);
858           }
859           local_in_reg[reg].start_address_ = address;
860           local_in_reg[reg].is_live_ = true;
861         }
862         break;
863 
864       case DBG_END_LOCAL:
865         reg = DecodeUnsignedLeb128(&stream);
866         if (reg > code_item->registers_size_) {
867           LOG(ERROR) << "invalid stream - reg > reg size (" << reg << " > "
868                      << code_item->registers_size_ << ") in " << GetLocation();
869           return;
870         }
871 
872         if (need_locals) {
873           InvokeLocalCbIfLive(context, reg, address, local_in_reg, local_cb);
874           local_in_reg[reg].is_live_ = false;
875         }
876         break;
877 
878       case DBG_RESTART_LOCAL:
879         reg = DecodeUnsignedLeb128(&stream);
880         if (reg > code_item->registers_size_) {
881           LOG(ERROR) << "invalid stream - reg > reg size (" << reg << " > "
882                      << code_item->registers_size_ << ") in " << GetLocation();
883           return;
884         }
885 
886         if (need_locals) {
887           if (local_in_reg[reg].name_ == NULL || local_in_reg[reg].descriptor_ == NULL) {
888             LOG(ERROR) << "invalid stream - no name or descriptor in " << GetLocation();
889             return;
890           }
891 
892           // If the register is live, the "restart" is superfluous,
893           // and we don't want to mess with the existing start address.
894           if (!local_in_reg[reg].is_live_) {
895             local_in_reg[reg].start_address_ = address;
896             local_in_reg[reg].is_live_ = true;
897           }
898         }
899         break;
900 
901       case DBG_SET_PROLOGUE_END:
902       case DBG_SET_EPILOGUE_BEGIN:
903       case DBG_SET_FILE:
904         break;
905 
906       default: {
907         int adjopcode = opcode - DBG_FIRST_SPECIAL;
908 
909         address += adjopcode / DBG_LINE_RANGE;
910         line += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);
911 
912         if (position_cb != NULL) {
913           if (position_cb(context, address, line)) {
914             // early exit
915             return;
916           }
917         }
918         break;
919       }
920     }
921   }
922 }
923 
DecodeDebugInfo(const CodeItem * code_item,bool is_static,uint32_t method_idx,DexDebugNewPositionCb position_cb,DexDebugNewLocalCb local_cb,void * context) const924 void DexFile::DecodeDebugInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx,
925                               DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
926                               void* context) const {
927   DCHECK(code_item != nullptr);
928   const byte* stream = GetDebugInfoStream(code_item);
929   std::unique_ptr<LocalInfo[]> local_in_reg(local_cb != NULL ?
930                                       new LocalInfo[code_item->registers_size_] :
931                                       NULL);
932   if (stream != NULL) {
933     DecodeDebugInfo0(code_item, is_static, method_idx, position_cb, local_cb, context, stream, &local_in_reg[0]);
934   }
935   for (int reg = 0; reg < code_item->registers_size_; reg++) {
936     InvokeLocalCbIfLive(context, reg, code_item->insns_size_in_code_units_, &local_in_reg[0], local_cb);
937   }
938 }
939 
LineNumForPcCb(void * raw_context,uint32_t address,uint32_t line_num)940 bool DexFile::LineNumForPcCb(void* raw_context, uint32_t address, uint32_t line_num) {
941   LineNumFromPcContext* context = reinterpret_cast<LineNumFromPcContext*>(raw_context);
942 
943   // We know that this callback will be called in
944   // ascending address order, so keep going until we find
945   // a match or we've just gone past it.
946   if (address > context->address_) {
947     // The line number from the previous positions callback
948     // wil be the final result.
949     return true;
950   } else {
951     context->line_num_ = line_num;
952     return address == context->address_;
953   }
954 }
955 
IsMultiDexLocation(const char * location)956 bool DexFile::IsMultiDexLocation(const char* location) {
957   return strrchr(location, kMultiDexSeparator) != nullptr;
958 }
959 
GetMultiDexClassesDexName(size_t number,const char * dex_location)960 std::string DexFile::GetMultiDexClassesDexName(size_t number, const char* dex_location) {
961   if (number == 0) {
962     return dex_location;
963   } else {
964     return StringPrintf("%s" kMultiDexSeparatorString "classes%zu.dex", dex_location, number + 1);
965   }
966 }
967 
GetDexCanonicalLocation(const char * dex_location)968 std::string DexFile::GetDexCanonicalLocation(const char* dex_location) {
969   CHECK_NE(dex_location, static_cast<const char*>(nullptr));
970   std::string base_location = GetBaseLocation(dex_location);
971   const char* suffix = dex_location + base_location.size();
972   DCHECK(suffix[0] == 0 || suffix[0] == kMultiDexSeparator);
973   UniqueCPtr<const char[]> path(realpath(base_location.c_str(), nullptr));
974   if (path != nullptr && path.get() != base_location) {
975     return std::string(path.get()) + suffix;
976   } else if (suffix[0] == 0) {
977     return base_location;
978   } else {
979     return dex_location;
980   }
981 }
982 
operator <<(std::ostream & os,const DexFile & dex_file)983 std::ostream& operator<<(std::ostream& os, const DexFile& dex_file) {
984   os << StringPrintf("[DexFile: %s dex-checksum=%08x location-checksum=%08x %p-%p]",
985                      dex_file.GetLocation().c_str(),
986                      dex_file.GetHeader().checksum_, dex_file.GetLocationChecksum(),
987                      dex_file.Begin(), dex_file.Begin() + dex_file.Size());
988   return os;
989 }
990 
ToString() const991 std::string Signature::ToString() const {
992   if (dex_file_ == nullptr) {
993     CHECK(proto_id_ == nullptr);
994     return "<no signature>";
995   }
996   const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
997   std::string result;
998   if (params == nullptr) {
999     result += "()";
1000   } else {
1001     result += "(";
1002     for (uint32_t i = 0; i < params->Size(); ++i) {
1003       result += dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_);
1004     }
1005     result += ")";
1006   }
1007   result += dex_file_->StringByTypeIdx(proto_id_->return_type_idx_);
1008   return result;
1009 }
1010 
operator ==(const StringPiece & rhs) const1011 bool Signature::operator==(const StringPiece& rhs) const {
1012   if (dex_file_ == nullptr) {
1013     return false;
1014   }
1015   StringPiece tail(rhs);
1016   if (!tail.starts_with("(")) {
1017     return false;  // Invalid signature
1018   }
1019   tail.remove_prefix(1);  // "(";
1020   const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
1021   if (params != nullptr) {
1022     for (uint32_t i = 0; i < params->Size(); ++i) {
1023       StringPiece param(dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_));
1024       if (!tail.starts_with(param)) {
1025         return false;
1026       }
1027       tail.remove_prefix(param.length());
1028     }
1029   }
1030   if (!tail.starts_with(")")) {
1031     return false;
1032   }
1033   tail.remove_prefix(1);  // ")";
1034   return tail == dex_file_->StringByTypeIdx(proto_id_->return_type_idx_);
1035 }
1036 
operator <<(std::ostream & os,const Signature & sig)1037 std::ostream& operator<<(std::ostream& os, const Signature& sig) {
1038   return os << sig.ToString();
1039 }
1040 
1041 // Decodes the header section from the class data bytes.
ReadClassDataHeader()1042 void ClassDataItemIterator::ReadClassDataHeader() {
1043   CHECK(ptr_pos_ != NULL);
1044   header_.static_fields_size_ = DecodeUnsignedLeb128(&ptr_pos_);
1045   header_.instance_fields_size_ = DecodeUnsignedLeb128(&ptr_pos_);
1046   header_.direct_methods_size_ = DecodeUnsignedLeb128(&ptr_pos_);
1047   header_.virtual_methods_size_ = DecodeUnsignedLeb128(&ptr_pos_);
1048 }
1049 
ReadClassDataField()1050 void ClassDataItemIterator::ReadClassDataField() {
1051   field_.field_idx_delta_ = DecodeUnsignedLeb128(&ptr_pos_);
1052   field_.access_flags_ = DecodeUnsignedLeb128(&ptr_pos_);
1053   if (last_idx_ != 0 && field_.field_idx_delta_ == 0) {
1054     LOG(WARNING) << "Duplicate field in " << dex_file_.GetLocation();
1055   }
1056 }
1057 
ReadClassDataMethod()1058 void ClassDataItemIterator::ReadClassDataMethod() {
1059   method_.method_idx_delta_ = DecodeUnsignedLeb128(&ptr_pos_);
1060   method_.access_flags_ = DecodeUnsignedLeb128(&ptr_pos_);
1061   method_.code_off_ = DecodeUnsignedLeb128(&ptr_pos_);
1062   if (last_idx_ != 0 && method_.method_idx_delta_ == 0) {
1063     LOG(WARNING) << "Duplicate method in " << dex_file_.GetLocation();
1064   }
1065 }
1066 
1067 // Read a signed integer.  "zwidth" is the zero-based byte count.
ReadSignedInt(const byte * ptr,int zwidth)1068 static int32_t ReadSignedInt(const byte* ptr, int zwidth) {
1069   int32_t val = 0;
1070   for (int i = zwidth; i >= 0; --i) {
1071     val = ((uint32_t)val >> 8) | (((int32_t)*ptr++) << 24);
1072   }
1073   val >>= (3 - zwidth) * 8;
1074   return val;
1075 }
1076 
1077 // Read an unsigned integer.  "zwidth" is the zero-based byte count,
1078 // "fill_on_right" indicates which side we want to zero-fill from.
ReadUnsignedInt(const byte * ptr,int zwidth,bool fill_on_right)1079 static uint32_t ReadUnsignedInt(const byte* ptr, int zwidth, bool fill_on_right) {
1080   uint32_t val = 0;
1081   if (!fill_on_right) {
1082     for (int i = zwidth; i >= 0; --i) {
1083       val = (val >> 8) | (((uint32_t)*ptr++) << 24);
1084     }
1085     val >>= (3 - zwidth) * 8;
1086   } else {
1087     for (int i = zwidth; i >= 0; --i) {
1088       val = (val >> 8) | (((uint32_t)*ptr++) << 24);
1089     }
1090   }
1091   return val;
1092 }
1093 
1094 // Read a signed long.  "zwidth" is the zero-based byte count.
ReadSignedLong(const byte * ptr,int zwidth)1095 static int64_t ReadSignedLong(const byte* ptr, int zwidth) {
1096   int64_t val = 0;
1097   for (int i = zwidth; i >= 0; --i) {
1098     val = ((uint64_t)val >> 8) | (((int64_t)*ptr++) << 56);
1099   }
1100   val >>= (7 - zwidth) * 8;
1101   return val;
1102 }
1103 
1104 // Read an unsigned long.  "zwidth" is the zero-based byte count,
1105 // "fill_on_right" indicates which side we want to zero-fill from.
ReadUnsignedLong(const byte * ptr,int zwidth,bool fill_on_right)1106 static uint64_t ReadUnsignedLong(const byte* ptr, int zwidth, bool fill_on_right) {
1107   uint64_t val = 0;
1108   if (!fill_on_right) {
1109     for (int i = zwidth; i >= 0; --i) {
1110       val = (val >> 8) | (((uint64_t)*ptr++) << 56);
1111     }
1112     val >>= (7 - zwidth) * 8;
1113   } else {
1114     for (int i = zwidth; i >= 0; --i) {
1115       val = (val >> 8) | (((uint64_t)*ptr++) << 56);
1116     }
1117   }
1118   return val;
1119 }
1120 
EncodedStaticFieldValueIterator(const DexFile & dex_file,Handle<mirror::DexCache> * dex_cache,Handle<mirror::ClassLoader> * class_loader,ClassLinker * linker,const DexFile::ClassDef & class_def)1121 EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator(const DexFile& dex_file,
1122                                                                  Handle<mirror::DexCache>* dex_cache,
1123                                                                  Handle<mirror::ClassLoader>* class_loader,
1124                                                                  ClassLinker* linker,
1125                                                                  const DexFile::ClassDef& class_def)
1126     : dex_file_(dex_file), dex_cache_(dex_cache), class_loader_(class_loader), linker_(linker),
1127       array_size_(), pos_(-1), type_(kByte) {
1128   DCHECK(dex_cache != nullptr);
1129   DCHECK(class_loader != nullptr);
1130   ptr_ = dex_file.GetEncodedStaticFieldValuesArray(class_def);
1131   if (ptr_ == NULL) {
1132     array_size_ = 0;
1133   } else {
1134     array_size_ = DecodeUnsignedLeb128(&ptr_);
1135   }
1136   if (array_size_ > 0) {
1137     Next();
1138   }
1139 }
1140 
Next()1141 void EncodedStaticFieldValueIterator::Next() {
1142   pos_++;
1143   if (pos_ >= array_size_) {
1144     return;
1145   }
1146   byte value_type = *ptr_++;
1147   byte value_arg = value_type >> kEncodedValueArgShift;
1148   size_t width = value_arg + 1;  // assume and correct later
1149   type_ = static_cast<ValueType>(value_type & kEncodedValueTypeMask);
1150   switch (type_) {
1151   case kBoolean:
1152     jval_.i = (value_arg != 0) ? 1 : 0;
1153     width = 0;
1154     break;
1155   case kByte:
1156     jval_.i = ReadSignedInt(ptr_, value_arg);
1157     CHECK(IsInt(8, jval_.i));
1158     break;
1159   case kShort:
1160     jval_.i = ReadSignedInt(ptr_, value_arg);
1161     CHECK(IsInt(16, jval_.i));
1162     break;
1163   case kChar:
1164     jval_.i = ReadUnsignedInt(ptr_, value_arg, false);
1165     CHECK(IsUint(16, jval_.i));
1166     break;
1167   case kInt:
1168     jval_.i = ReadSignedInt(ptr_, value_arg);
1169     break;
1170   case kLong:
1171     jval_.j = ReadSignedLong(ptr_, value_arg);
1172     break;
1173   case kFloat:
1174     jval_.i = ReadUnsignedInt(ptr_, value_arg, true);
1175     break;
1176   case kDouble:
1177     jval_.j = ReadUnsignedLong(ptr_, value_arg, true);
1178     break;
1179   case kString:
1180   case kType:
1181     jval_.i = ReadUnsignedInt(ptr_, value_arg, false);
1182     break;
1183   case kField:
1184   case kMethod:
1185   case kEnum:
1186   case kArray:
1187   case kAnnotation:
1188     UNIMPLEMENTED(FATAL) << ": type " << type_;
1189     break;
1190   case kNull:
1191     jval_.l = NULL;
1192     width = 0;
1193     break;
1194   default:
1195     LOG(FATAL) << "Unreached";
1196   }
1197   ptr_ += width;
1198 }
1199 
1200 template<bool kTransactionActive>
ReadValueToField(mirror::ArtField * field) const1201 void EncodedStaticFieldValueIterator::ReadValueToField(mirror::ArtField* field) const {
1202   switch (type_) {
1203     case kBoolean: field->SetBoolean<kTransactionActive>(field->GetDeclaringClass(), jval_.z); break;
1204     case kByte:    field->SetByte<kTransactionActive>(field->GetDeclaringClass(), jval_.b); break;
1205     case kShort:   field->SetShort<kTransactionActive>(field->GetDeclaringClass(), jval_.s); break;
1206     case kChar:    field->SetChar<kTransactionActive>(field->GetDeclaringClass(), jval_.c); break;
1207     case kInt:     field->SetInt<kTransactionActive>(field->GetDeclaringClass(), jval_.i); break;
1208     case kLong:    field->SetLong<kTransactionActive>(field->GetDeclaringClass(), jval_.j); break;
1209     case kFloat:   field->SetFloat<kTransactionActive>(field->GetDeclaringClass(), jval_.f); break;
1210     case kDouble:  field->SetDouble<kTransactionActive>(field->GetDeclaringClass(), jval_.d); break;
1211     case kNull:    field->SetObject<kTransactionActive>(field->GetDeclaringClass(), NULL); break;
1212     case kString: {
1213       CHECK(!kMovingFields);
1214       mirror::String* resolved = linker_->ResolveString(dex_file_, jval_.i, *dex_cache_);
1215       field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
1216       break;
1217     }
1218     case kType: {
1219       CHECK(!kMovingFields);
1220       mirror::Class* resolved = linker_->ResolveType(dex_file_, jval_.i, *dex_cache_,
1221                                                      *class_loader_);
1222       field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
1223       break;
1224     }
1225     default: UNIMPLEMENTED(FATAL) << ": type " << type_;
1226   }
1227 }
1228 template void EncodedStaticFieldValueIterator::ReadValueToField<true>(mirror::ArtField* field) const;
1229 template void EncodedStaticFieldValueIterator::ReadValueToField<false>(mirror::ArtField* field) const;
1230 
CatchHandlerIterator(const DexFile::CodeItem & code_item,uint32_t address)1231 CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address) {
1232   handler_.address_ = -1;
1233   int32_t offset = -1;
1234 
1235   // Short-circuit the overwhelmingly common cases.
1236   switch (code_item.tries_size_) {
1237     case 0:
1238       break;
1239     case 1: {
1240       const DexFile::TryItem* tries = DexFile::GetTryItems(code_item, 0);
1241       uint32_t start = tries->start_addr_;
1242       if (address >= start) {
1243         uint32_t end = start + tries->insn_count_;
1244         if (address < end) {
1245           offset = tries->handler_off_;
1246         }
1247       }
1248       break;
1249     }
1250     default:
1251       offset = DexFile::FindCatchHandlerOffset(code_item, address);
1252   }
1253   Init(code_item, offset);
1254 }
1255 
CatchHandlerIterator(const DexFile::CodeItem & code_item,const DexFile::TryItem & try_item)1256 CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item,
1257                                            const DexFile::TryItem& try_item) {
1258   handler_.address_ = -1;
1259   Init(code_item, try_item.handler_off_);
1260 }
1261 
Init(const DexFile::CodeItem & code_item,int32_t offset)1262 void CatchHandlerIterator::Init(const DexFile::CodeItem& code_item,
1263                                 int32_t offset) {
1264   if (offset >= 0) {
1265     Init(DexFile::GetCatchHandlerData(code_item, offset));
1266   } else {
1267     // Not found, initialize as empty
1268     current_data_ = NULL;
1269     remaining_count_ = -1;
1270     catch_all_ = false;
1271     DCHECK(!HasNext());
1272   }
1273 }
1274 
Init(const byte * handler_data)1275 void CatchHandlerIterator::Init(const byte* handler_data) {
1276   current_data_ = handler_data;
1277   remaining_count_ = DecodeSignedLeb128(&current_data_);
1278 
1279   // If remaining_count_ is non-positive, then it is the negative of
1280   // the number of catch types, and the catches are followed by a
1281   // catch-all handler.
1282   if (remaining_count_ <= 0) {
1283     catch_all_ = true;
1284     remaining_count_ = -remaining_count_;
1285   } else {
1286     catch_all_ = false;
1287   }
1288   Next();
1289 }
1290 
Next()1291 void CatchHandlerIterator::Next() {
1292   if (remaining_count_ > 0) {
1293     handler_.type_idx_ = DecodeUnsignedLeb128(&current_data_);
1294     handler_.address_  = DecodeUnsignedLeb128(&current_data_);
1295     remaining_count_--;
1296     return;
1297   }
1298 
1299   if (catch_all_) {
1300     handler_.type_idx_ = DexFile::kDexNoIndex16;
1301     handler_.address_  = DecodeUnsignedLeb128(&current_data_);
1302     catch_all_ = false;
1303     return;
1304   }
1305 
1306   // no more handler
1307   remaining_count_ = -1;
1308 }
1309 
1310 }  // namespace art
1311