1 /* 2 * Copyright (C) 2017 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 "source_transform.h" 18 19 #include <inttypes.h> 20 21 #include <memory> 22 23 #include <android-base/logging.h> 24 25 #include "dex/code_item_accessors-inl.h" 26 #include "dex/art_dex_file_loader.h" 27 #include "dex/dex_file.h" 28 #include "dex/dex_file_loader.h" 29 #include "dex/dex_instruction.h" 30 31 namespace art { 32 namespace Test983SourceTransformVerify { 33 34 // The hook we are using. 35 void VerifyClassData(jint class_data_len, const unsigned char* class_data) { 36 // Due to b/72402467 the class_data_len might just be an estimate. 37 CHECK_GE(static_cast<size_t>(class_data_len), sizeof(DexFile::Header)); 38 const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(class_data); 39 uint32_t header_file_size = header->file_size_; 40 CHECK_LE(static_cast<jint>(header_file_size), class_data_len); 41 class_data_len = static_cast<jint>(header_file_size); 42 43 const ArtDexFileLoader dex_file_loader; 44 std::string error; 45 std::unique_ptr<const DexFile> dex(dex_file_loader.Open(class_data, 46 class_data_len, 47 "fake_location.dex", 48 /*location_checksum*/ 0, 49 /*oat_dex_file*/ nullptr, 50 /*verify*/ true, 51 /*verify_checksum*/ true, 52 &error)); 53 CHECK(dex.get() != nullptr) << "Failed to verify dex: " << error; 54 for (uint32_t i = 0; i < dex->NumClassDefs(); i++) { 55 const DexFile::ClassDef& def = dex->GetClassDef(i); 56 const uint8_t* data_item = dex->GetClassData(def); 57 if (data_item == nullptr) { 58 continue; 59 } 60 for (ClassDataItemIterator it(*dex, data_item); it.HasNext(); it.Next()) { 61 if (!it.IsAtMethod() || it.GetMethodCodeItem() == nullptr) { 62 continue; 63 } 64 for (const DexInstructionPcPair& pair : 65 art::CodeItemInstructionAccessor(*dex, it.GetMethodCodeItem())) { 66 const Instruction& inst = pair.Inst(); 67 int forbidden_flags = (Instruction::kVerifyError | Instruction::kVerifyRuntimeOnly); 68 if (inst.Opcode() == Instruction::RETURN_VOID_NO_BARRIER || 69 (inst.GetVerifyExtraFlags() & forbidden_flags) != 0) { 70 LOG(FATAL) << "Unexpected instruction found in " << dex->PrettyMethod(it.GetMemberIndex()) 71 << " [Dex PC: 0x" << std::hex << pair.DexPc() << std::dec << "] : " 72 << inst.DumpString(dex.get()) << std::endl; 73 } 74 } 75 } 76 } 77 } 78 79 } // namespace Test983SourceTransformVerify 80 } // namespace art 81