diff options
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 47 | ||||
| -rw-r--r-- | dex2oat/dex2oat.cc | 1 | ||||
| -rw-r--r-- | test/719-dm-verify-redefinition/check | 22 | ||||
| -rw-r--r-- | test/719-dm-verify-redefinition/expected.txt | 3 | ||||
| -rw-r--r-- | test/719-dm-verify-redefinition/info.txt | 2 | ||||
| -rw-r--r-- | test/719-dm-verify-redefinition/run | 18 | ||||
| -rw-r--r-- | test/719-dm-verify-redefinition/src/Main.java | 27 | ||||
| -rw-r--r-- | test/719-dm-verify-redefinition/src/java/util/BitSet.java | 20 | ||||
| -rw-r--r-- | test/knownfailures.json | 8 |
9 files changed, 148 insertions, 0 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index e440eec735..d46cffb1e8 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -1765,6 +1765,42 @@ static void LoadAndUpdateStatus(const ClassAccessor& accessor, } } +// Returns true if any of the given dex files define a class from the boot classpath. +static bool DexFilesRedefineBootClasses( + const std::vector<const DexFile*>& dex_files, + TimingLogger* timings) { + TimingLogger::ScopedTiming t("Fast Verify: Boot Class Redefinition Check", timings); + + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + Thread* self = Thread::Current(); + ScopedObjectAccess soa(self); + + bool foundRedefinition = false; + for (const DexFile* dex_file : dex_files) { + for (ClassAccessor accessor : dex_file->GetClasses()) { + const char* descriptor = accessor.GetDescriptor(); + StackHandleScope<1> hs_class(self); + Handle<mirror::Class> klass = + hs_class.NewHandle(class_linker->FindSystemClass(self, descriptor)); + if (klass == nullptr) { + self->ClearException(); + } else { + LOG(WARNING) << "Redefinition of boot class " << descriptor + << " App dex file: " << accessor.GetDexFile().GetLocation() + << " Boot dex file: " << klass->GetDexFile().GetLocation(); + foundRedefinition = true; + if (!VLOG_IS_ON(verifier)) { + // If we are not in verbose mode, return early. + // Otherwise continue and log all the collisions for easier debugging. + return true; + } + } + } + } + + return foundRedefinition; +} + bool CompilerDriver::FastVerify(jobject jclass_loader, const std::vector<const DexFile*>& dex_files, TimingLogger* timings, @@ -1776,6 +1812,17 @@ bool CompilerDriver::FastVerify(jobject jclass_loader, return false; } TimingLogger::ScopedTiming t("Fast Verify", timings); + + // We cannot do fast verification if the app redefines classes from the boot classpath. + // Vdex does not record resolution chains for boot classes and we might wrongfully + // resolve a class to the app when it should have been resolved to the boot classpath + // (e.g. if we verified against the SDK and the app redefines a boot class which is not + // in the SDK.) + if (DexFilesRedefineBootClasses(dex_files, timings)) { + LOG(WARNING) << "Found redefinition of boot classes. Not doing fast verification."; + return false; + } + ScopedObjectAccess soa(Thread::Current()); StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 35af918757..808ad6c212 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -1367,6 +1367,7 @@ class Dex2Oat final { LOG(WARNING) << "Could not open vdex file in DexMetadata archive: " << error_msg; } else { input_vdex_file_ = std::make_unique<VdexFile>(std::move(input_file)); + VLOG(verifier) << "Doing fast verification with vdex from DexMetadata archive"; } } } diff --git a/test/719-dm-verify-redefinition/check b/test/719-dm-verify-redefinition/check new file mode 100644 index 0000000000..b3c717c280 --- /dev/null +++ b/test/719-dm-verify-redefinition/check @@ -0,0 +1,22 @@ +#!/bin/bash +# +# Copyright (C) 2019 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. + +# Search for the redefinition line and remove unnecessary tags. +sed -e 's/^dex2oat[d]\?\(\|32\|64\)\ W.*\] Found redefinition of boot classes\. Not doing fast verification\./Found redefinition of boot classes\. Not doing fast verification\./g' "$2" > "$2.tmp1" +# Remove all other dex2oat log lines. +grep -v dex2oat "$2.tmp1" >> "$2.tmp2" + +./default-check "$1" "$2.tmp2" diff --git a/test/719-dm-verify-redefinition/expected.txt b/test/719-dm-verify-redefinition/expected.txt new file mode 100644 index 0000000000..64fb4ea7ea --- /dev/null +++ b/test/719-dm-verify-redefinition/expected.txt @@ -0,0 +1,3 @@ +Found redefinition of boot classes. Not doing fast verification. +Hello, world! +Correct resolution of boot class. diff --git a/test/719-dm-verify-redefinition/info.txt b/test/719-dm-verify-redefinition/info.txt new file mode 100644 index 0000000000..1229bdb7db --- /dev/null +++ b/test/719-dm-verify-redefinition/info.txt @@ -0,0 +1,2 @@ +Verifies that the vdex file from a DexMetadata archive is discarded +if the app redefines boot classes. diff --git a/test/719-dm-verify-redefinition/run b/test/719-dm-verify-redefinition/run new file mode 100644 index 0000000000..8e568b59fb --- /dev/null +++ b/test/719-dm-verify-redefinition/run @@ -0,0 +1,18 @@ +#!/bin/bash +# +# Copyright (C) 2019 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. + +export ANDROID_LOG_TAGS='*:w' +exec ${RUN} --external-log-tags --dm "${@}" diff --git a/test/719-dm-verify-redefinition/src/Main.java b/test/719-dm-verify-redefinition/src/Main.java new file mode 100644 index 0000000000..37575b6fcf --- /dev/null +++ b/test/719-dm-verify-redefinition/src/Main.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2019 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. + */ +import java.util.BitSet; + +public class Main { + public static void main(String[] args) { + System.out.println("Hello, world!"); + if (BitSet.class.getClassLoader().equals(String.class.getClassLoader())) { + System.out.println("Correct resolution of boot class."); + } else { + System.out.println("Bogus resolution of boot class."); + } + } +} diff --git a/test/719-dm-verify-redefinition/src/java/util/BitSet.java b/test/719-dm-verify-redefinition/src/java/util/BitSet.java new file mode 100644 index 0000000000..5d91fd8d59 --- /dev/null +++ b/test/719-dm-verify-redefinition/src/java/util/BitSet.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2019 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. + */ + +package java.util; + +public class BitSet { +} diff --git a/test/knownfailures.json b/test/knownfailures.json index c4764e8c2d..b97b4c1b88 100644 --- a/test/knownfailures.json +++ b/test/knownfailures.json @@ -1177,5 +1177,13 @@ "variant": "jit-on-first-use", "bug": "b/120112467", "description": [ "Fails on Android Build hosts with uncaught std::bad_alloc." ] + }, + { + "tests": ["719-dm-verify-redefinition"], + "variant": "jvm | speed-profile | interp-ac | target", + "description": ["Doesn't run on RI because of boot class redefintion.", + "Doesn't work with profiles because the run-test is not setup to", + "support both. It also needs full verification, so no interp-ac.", + "Requires zip, which isn't available on device"] } ] |