ART: Fix CFI test wrt/ PIC
PIC boot images can't be loaded with dlopen, as their base is zero,
but we have an expectant address. Turn off in-process unwinding
in 137-cfi by checking the boot image oat file type.
Keep a non-owned referenced to the oat file in image space to simplify
access.
Change-Id: Ia2b525f9b2ecbc80b433f09e04ebece4cb6f2d2b
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index dc8a3d1..c4d978f 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -808,18 +808,11 @@
}
const OatFile* ClassLinker::GetBootOatFile() {
- // To grab the boot oat, look at the dex files in the boot classpath. Any of those is fine, as
- // they were all compiled into the same oat file. So grab the first one, which is guaranteed to
- // exist if the boot class-path isn't empty.
- if (boot_class_path_.empty()) {
+ gc::space::ImageSpace* image_space = Runtime::Current()->GetHeap()->GetImageSpace();
+ if (image_space == nullptr) {
return nullptr;
}
- const DexFile* boot_dex_file = boot_class_path_[0];
- // Is it from an oat file?
- if (boot_dex_file->GetOatDexFile() != nullptr) {
- return boot_dex_file->GetOatDexFile()->GetOatFile();
- }
- return nullptr;
+ return image_space->GetOatFile();
}
const OatFile* ClassLinker::GetPrimaryOatFile() {
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index f7ceb84..1923d24 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -755,6 +755,7 @@
DCHECK(!error_msg->empty());
return nullptr;
}
+ space->oat_file_non_owned_ = space->oat_file_.get();
if (validate_oat_file && !space->ValidateOatFile(error_msg)) {
DCHECK(!error_msg->empty());
@@ -838,10 +839,12 @@
return true;
}
+
const OatFile* ImageSpace::GetOatFile() const {
- return oat_file_.get();
+ return oat_file_non_owned_;
}
+
OatFile* ImageSpace::ReleaseOatFile() {
CHECK(oat_file_.get() != nullptr);
return oat_file_.release();
diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h
index 54dc7a6..93ff8aa 100644
--- a/runtime/gc/space/image_space.h
+++ b/runtime/gc/space/image_space.h
@@ -152,6 +152,10 @@
// the ClassLinker during it's initialization.
std::unique_ptr<OatFile> oat_file_;
+ // There are times when we need to find the boot image oat file. As
+ // we release ownership during startup, keep a non-owned reference.
+ const OatFile* oat_file_non_owned_;
+
const std::string image_location_;
DISALLOW_COPY_AND_ASSIGN(ImageSpace);
diff --git a/test/137-cfi/cfi.cc b/test/137-cfi/cfi.cc
index 83f7711..601fbaa 100644
--- a/test/137-cfi/cfi.cc
+++ b/test/137-cfi/cfi.cc
@@ -29,6 +29,9 @@
#include "base/logging.h"
#include "base/macros.h"
+#include "gc/heap.h"
+#include "gc/space/image_space.h"
+#include "oat_file.h"
#include "utils.h"
namespace art {
@@ -84,8 +87,26 @@
}
#endif
+// Currently we have to fall back to our own loader for the boot image when it's compiled PIC
+// because its base is zero. Thus in-process unwinding through it won't work. This is a helper
+// detecting this.
+#if __linux__
+static bool IsPicImage() {
+ gc::space::ImageSpace* image_space = Runtime::Current()->GetHeap()->GetImageSpace();
+ CHECK(image_space != nullptr); // We should be running with an image.
+ const OatFile* oat_file = image_space->GetOatFile();
+ CHECK(oat_file != nullptr); // We should have an oat file to go with the image.
+ return oat_file->IsPic();
+}
+#endif
+
extern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindInProcess(JNIEnv*, jobject, jint, jboolean) {
#if __linux__
+ if (IsPicImage()) {
+ LOG(INFO) << "Image is pic, in-process unwinding check bypassed.";
+ return JNI_TRUE;
+ }
+
// TODO: What to do on Valgrind?
std::unique_ptr<Backtrace> bt(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, GetTid()));