diff options
| author | 2018-02-14 14:00:46 -0800 | |
|---|---|---|
| committer | 2018-02-15 22:45:22 -0800 | |
| commit | 59484b9fbbfd79cf485fbcdddffe35c706c5f70d (patch) | |
| tree | fea1d7098390938be408eaf77f1ec0e8acd9b8c8 | |
| parent | 7fe39afe80098d147e34149dac1d6304e858fe44 (diff) | |
ART: Refactor run-test 983 dex verification
Split the source for use in run-tests (using libdexfile) and
CTS (using slicer). In preparation for compilation with the
NDK.
Test: m test-art-host
Test: m cts
Change-Id: Ie514445d90c77391ec685b53726f1f9dd50f1991
| -rw-r--r-- | test/983-source-transform-verify/source_transform.cc | 70 | ||||
| -rw-r--r-- | test/983-source-transform-verify/source_transform.h | 30 | ||||
| -rw-r--r-- | test/983-source-transform-verify/source_transform_art.cc | 80 | ||||
| -rw-r--r-- | test/983-source-transform-verify/source_transform_slicer.cc | 41 | ||||
| -rw-r--r-- | test/Android.bp | 17 |
5 files changed, 165 insertions, 73 deletions
diff --git a/test/983-source-transform-verify/source_transform.cc b/test/983-source-transform-verify/source_transform.cc index 26c5668681..9e65a9964c 100644 --- a/test/983-source-transform-verify/source_transform.cc +++ b/test/983-source-transform-verify/source_transform.cc @@ -14,25 +14,14 @@ * limitations under the License. */ -#include <inttypes.h> +#include "source_transform.h" -#include <cstdio> -#include <cstring> -#include <iostream> -#include <sstream> -#include <vector> +#include "jni.h" #include "android-base/stringprintf.h" -#include "jni.h" #include "jvmti.h" #include "scoped_local_ref.h" -#include "dex/code_item_accessors-inl.h" -#include "dex/dex_file_loader.h" -#include "dex/dex_file.h" -#include "dex/dex_file_loader.h" -#include "dex/dex_instruction.h" - // Test infrastructure #include "jvmti_helper.h" #include "test_env.h" @@ -42,13 +31,12 @@ namespace Test983SourceTransformVerify { constexpr bool kSkipInitialLoad = true; -static void Println(JNIEnv* env, std::ostringstream msg_stream) { - std::string msg = msg_stream.str(); +static void Println(JNIEnv* env, const char* msg) { ScopedLocalRef<jclass> test_klass(env, env->FindClass("art/Test983")); jmethodID println_method = env->GetStaticMethodID(test_klass.get(), "doPrintln", "(Ljava/lang/String;)V"); - ScopedLocalRef<jstring> data(env, env->NewStringUTF(msg.c_str())); + ScopedLocalRef<jstring> data(env, env->NewStringUTF(msg)); env->CallStaticVoidMethod(test_klass.get(), println_method, data.get()); } @@ -68,58 +56,12 @@ void JNICALL CheckDexFileHook(jvmtiEnv* jvmti_env ATTRIBUTE_UNUSED, // repeatable we only care about things that come from RetransformClasses. return; } - Println(env, std::ostringstream() << "Dex file hook for " << name); + Println(env, android::base::StringPrintf("Dex file hook for %s", name).c_str()); if (IsJVM()) { return; } - // Due to b/72402467 the class_data_len might just be an estimate. - CHECK_GE(static_cast<size_t>(class_data_len), sizeof(DexFile::Header)); - const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(class_data); - uint32_t header_file_size = header->file_size_; - CHECK_LE(static_cast<jint>(header_file_size), class_data_len); - class_data_len = static_cast<jint>(header_file_size); - - const DexFileLoader dex_file_loader; - std::string error; - std::unique_ptr<const DexFile> dex(dex_file_loader.Open(class_data, - class_data_len, - "fake_location.dex", - /*location_checksum*/ 0, - /*oat_dex_file*/ nullptr, - /*verify*/ true, - /*verify_checksum*/ true, - &error)); - if (dex.get() == nullptr) { - Println(env, std::ostringstream() << "Failed to verify dex file for " - << name << " because " << error); - return; - } - for (uint32_t i = 0; i < dex->NumClassDefs(); i++) { - const DexFile::ClassDef& def = dex->GetClassDef(i); - const uint8_t* data_item = dex->GetClassData(def); - if (data_item == nullptr) { - continue; - } - for (ClassDataItemIterator it(*dex, data_item); it.HasNext(); it.Next()) { - if (!it.IsAtMethod() || it.GetMethodCodeItem() == nullptr) { - continue; - } - for (const DexInstructionPcPair& pair : - art::CodeItemInstructionAccessor(*dex, it.GetMethodCodeItem())) { - const Instruction& inst = pair.Inst(); - int forbiden_flags = (Instruction::kVerifyError | Instruction::kVerifyRuntimeOnly); - if (inst.Opcode() == Instruction::RETURN_VOID_NO_BARRIER || - (inst.GetVerifyExtraFlags() & forbiden_flags) != 0) { - Println(env, std::ostringstream() << "Unexpected instruction found in " - << dex->PrettyMethod(it.GetMemberIndex()) - << " [Dex PC: 0x" << std::hex << pair.DexPc() - << std::dec << "] : " << inst.DumpString(dex.get())); - continue; - } - } - } - } + VerifyClassData(class_data_len, class_data); } // Get all capabilities except those related to retransformation. diff --git a/test/983-source-transform-verify/source_transform.h b/test/983-source-transform-verify/source_transform.h new file mode 100644 index 0000000000..2206498cc3 --- /dev/null +++ b/test/983-source-transform-verify/source_transform.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_TEST_983_SOURCE_TRANSFORM_VERIFY_SOURCE_TRANSFORM_H_ +#define ART_TEST_983_SOURCE_TRANSFORM_VERIFY_SOURCE_TRANSFORM_H_ + +#include <jni.h> + +namespace art { +namespace Test983SourceTransformVerify { + +void VerifyClassData(jint class_data_len, const unsigned char* class_data); + +} // namespace Test983SourceTransformVerify +} // namespace art + +#endif // ART_TEST_983_SOURCE_TRANSFORM_VERIFY_SOURCE_TRANSFORM_H_ diff --git a/test/983-source-transform-verify/source_transform_art.cc b/test/983-source-transform-verify/source_transform_art.cc new file mode 100644 index 0000000000..5353370ac6 --- /dev/null +++ b/test/983-source-transform-verify/source_transform_art.cc @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "source_transform.h" + +#include <inttypes.h> + +#include <memory> + +#include <android-base/logging.h> + +#include "dex/code_item_accessors-inl.h" +#include "dex/art_dex_file_loader.h" +#include "dex/dex_file.h" +#include "dex/dex_file_loader.h" +#include "dex/dex_instruction.h" + +namespace art { +namespace Test983SourceTransformVerify { + +// The hook we are using. +void VerifyClassData(jint class_data_len, const unsigned char* class_data) { + // Due to b/72402467 the class_data_len might just be an estimate. + CHECK_GE(static_cast<size_t>(class_data_len), sizeof(DexFile::Header)); + const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(class_data); + uint32_t header_file_size = header->file_size_; + CHECK_LE(static_cast<jint>(header_file_size), class_data_len); + class_data_len = static_cast<jint>(header_file_size); + + const ArtDexFileLoader dex_file_loader; + std::string error; + std::unique_ptr<const DexFile> dex(dex_file_loader.Open(class_data, + class_data_len, + "fake_location.dex", + /*location_checksum*/ 0, + /*oat_dex_file*/ nullptr, + /*verify*/ true, + /*verify_checksum*/ true, + &error)); + CHECK(dex.get() != nullptr) << "Failed to verify dex: " << error; + for (uint32_t i = 0; i < dex->NumClassDefs(); i++) { + const DexFile::ClassDef& def = dex->GetClassDef(i); + const uint8_t* data_item = dex->GetClassData(def); + if (data_item == nullptr) { + continue; + } + for (ClassDataItemIterator it(*dex, data_item); it.HasNext(); it.Next()) { + if (!it.IsAtMethod() || it.GetMethodCodeItem() == nullptr) { + continue; + } + for (const DexInstructionPcPair& pair : + art::CodeItemInstructionAccessor(*dex, it.GetMethodCodeItem())) { + const Instruction& inst = pair.Inst(); + int forbidden_flags = (Instruction::kVerifyError | Instruction::kVerifyRuntimeOnly); + if (inst.Opcode() == Instruction::RETURN_VOID_NO_BARRIER || + (inst.GetVerifyExtraFlags() & forbidden_flags) != 0) { + LOG(FATAL) << "Unexpected instruction found in " << dex->PrettyMethod(it.GetMemberIndex()) + << " [Dex PC: 0x" << std::hex << pair.DexPc() << std::dec << "] : " + << inst.DumpString(dex.get()) << std::endl; + } + } + } + } +} + +} // namespace Test983SourceTransformVerify +} // namespace art diff --git a/test/983-source-transform-verify/source_transform_slicer.cc b/test/983-source-transform-verify/source_transform_slicer.cc new file mode 100644 index 0000000000..abf32e752e --- /dev/null +++ b/test/983-source-transform-verify/source_transform_slicer.cc @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "source_transform.h" + +#pragma clang diagnostic push +// slicer defines its own CHECK. b/65422458 +#pragma push_macro("CHECK") +#undef CHECK + +// Slicer's headers have code that triggers these warnings. b/65298177 +#pragma clang diagnostic ignored "-Wsign-compare" +#include "reader.h" + +#pragma pop_macro("CHECK") +#pragma clang diagnostic pop + +namespace art { +namespace Test983SourceTransformVerify { + +// The hook we are using. +void VerifyClassData(jint class_data_len, const unsigned char* class_data) { + dex::Reader reader(class_data, class_data_len); + reader.CreateFullIr(); // This will verify all bytecode. +} + +} // namespace Test983SourceTransformVerify +} // namespace art diff --git a/test/Android.bp b/test/Android.bp index 8b88b09f7c..77160d36c1 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -289,6 +289,7 @@ art_cc_defaults { "909-attach-agent/attach.cc", "912-classes/classes_art.cc", "936-search-onload/search_onload.cc", + "983-source-transform-verify/source_transform_art.cc", "1940-ddms-ext/ddm_ext.cc", "1944-sudden-exit/sudden_exit.cc", ], @@ -313,21 +314,19 @@ art_cc_test_library { shared_libs: ["libartd"], } -art_cc_test_library { +cc_library_static { name: "libctstiagent", defaults: ["libtiagent-base-defaults"], + host_supported: false, + srcs: [ + "983-source-transform-verify/source_transform_slicer.cc", + ], whole_static_libs: [ - "libdexfile", - "libz", - "libziparchive", + "slicer", + "libz", // for slicer (using adler32). ], static_libs: [ "libbase", - "libcutils", - "libutils", - ], - shared_libs: [ - "liblog", ], header_libs: [ // This is needed to resolve the base/ header file in libdexfile. Unfortunately there are |