Remove opening of DexFile from pointer
Change-Id: I158e75e9e72f1dcc579742ff08c80d3f857852b3
diff --git a/src/common_test.h b/src/common_test.h
index 8491dbb..a7c5ea8 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -13,8 +13,10 @@
#include "compiler.h"
#include "constants.h"
#include "dex_file.h"
+#include "file.h"
#include "gtest/gtest.h"
#include "heap.h"
+#include "os.h"
#include "runtime.h"
#include "stl_util.h"
#include "stringprintf.h"
@@ -26,11 +28,22 @@
static inline const DexFile* OpenDexFileBase64(const char* base64,
const std::string& location) {
+ // decode base64
CHECK(base64 != NULL);
size_t length;
byte* dex_bytes = DecodeBase64(base64, &length);
CHECK(dex_bytes != NULL);
- const DexFile* dex_file = DexFile::OpenPtr(dex_bytes, length, location);
+
+ // write to provided file
+ UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
+ CHECK(file.get() != NULL);
+ if (!file->WriteFully(dex_bytes, length)) {
+ PLOG(FATAL) << "Failed to write base64 as dex file";
+ }
+ file.reset();
+
+ // read dex file
+ const DexFile* dex_file = DexFile::OpenFile(location, location, "");
CHECK(dex_file != NULL);
return dex_file;
}
diff --git a/src/dex_file.cc b/src/dex_file.cc
index d437a3f..b4cf837 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -71,29 +71,11 @@
}
void DexFile::ChangePermissions(int prot) const {
- closer_->ChangePermissions(prot);
-}
-
-DexFile::Closer::~Closer() {}
-
-DexFile::MmapCloser::MmapCloser(void* addr, size_t length) : addr_(addr), length_(length) {
- CHECK(addr != NULL);
-}
-DexFile::MmapCloser::~MmapCloser() {
- if (munmap(addr_, length_) == -1) {
- PLOG(INFO) << "munmap failed";
- }
-}
-void DexFile::MmapCloser::ChangePermissions(int prot) {
- if (mprotect(addr_, length_, prot) != 0) {
+ if (mprotect(mem_map_->GetAddress(), mem_map_->GetLength(), prot) != 0) {
PLOG(FATAL) << "Failed to change dex file permissions to " << prot;
}
}
-DexFile::PtrCloser::PtrCloser(byte* addr) : addr_(addr) {}
-DexFile::PtrCloser::~PtrCloser() { delete[] addr_; }
-void DexFile::PtrCloser::ChangePermissions(int prot) {}
-
const DexFile* DexFile::OpenFile(const std::string& filename,
const std::string& original_location,
const std::string& strip_location_prefix) {
@@ -116,16 +98,15 @@
return NULL;
}
size_t length = sbuf.st_size;
- void* addr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
- if (addr == MAP_FAILED) {
- PLOG(ERROR) << "mmap \"" << filename << "\" failed";
+ UniquePtr<MemMap> map(MemMap::Map(length, PROT_READ, MAP_PRIVATE, fd, 0));
+ if (map.get() == NULL) {
+ LOG(ERROR) << "mmap \"" << filename << "\" failed";
close(fd);
return NULL;
}
close(fd);
- byte* dex_file = reinterpret_cast<byte*>(addr);
- Closer* closer = new MmapCloser(addr, length);
- return Open(dex_file, length, location.ToString(), closer);
+ byte* dex_file = map->GetAddress();
+ return Open(dex_file, length, location.ToString(), map.release());
}
static const char* kClassesDex = "classes.dex";
@@ -368,15 +349,9 @@
// NOTREACHED
}
-const DexFile* DexFile::OpenPtr(byte* ptr, size_t length, const std::string& location) {
- CHECK(ptr != NULL);
- DexFile::Closer* closer = new PtrCloser(ptr);
- return Open(ptr, length, location, closer);
-}
-
const DexFile* DexFile::Open(const byte* dex_bytes, size_t length,
- const std::string& location, Closer* closer) {
- UniquePtr<DexFile> dex_file(new DexFile(dex_bytes, length, location, closer));
+ const std::string& location, MemMap* mem_map) {
+ UniquePtr<DexFile> dex_file(new DexFile(dex_bytes, length, location, mem_map));
if (!dex_file->Init()) {
return NULL;
} else {
diff --git a/src/dex_file.h b/src/dex_file.h
index e313d74..cb979ae 100644
--- a/src/dex_file.h
+++ b/src/dex_file.h
@@ -12,6 +12,7 @@
#include "jni.h"
#include "leb128.h"
#include "logging.h"
+#include "mem_map.h"
#include "mutex.h"
#include "stringpiece.h"
#include "strutil.h"
@@ -336,13 +337,6 @@
static const DexFile* OpenZip(const std::string& filename,
const std::string& strip_location_prefix);
- // Opens a .dex file from a new allocated pointer. location is used
- // to identify the source, for example "/system/framework/core.jar"
- // or "contrived-test-42". When initializing a ClassLinker from an
- // image, the location is used to match DexCaches the image to their
- // corresponding DexFiles.N
- static const DexFile* OpenPtr(byte* ptr, size_t length, const std::string& location);
-
// Closes a .dex file.
virtual ~DexFile();
@@ -844,45 +838,17 @@
void ChangePermissions(int prot) const;
private:
- // Helper class to deallocate underlying storage.
- class Closer {
- public:
- virtual ~Closer();
- virtual void ChangePermissions(int prot) = 0;
- };
-
- // Helper class to deallocate mmap-backed .dex files.
- class MmapCloser : public Closer {
- public:
- MmapCloser(void* addr, size_t length);
- virtual ~MmapCloser();
- virtual void ChangePermissions(int prot);
- private:
- void* addr_;
- size_t length_;
- };
-
- // Helper class for deallocating new/delete-backed .dex files.
- class PtrCloser : public Closer {
- public:
- PtrCloser(byte* addr);
- virtual ~PtrCloser();
- virtual void ChangePermissions(int prot);
- private:
- byte* addr_;
- };
-
// Opens a .dex file at the given address.
static const DexFile* Open(const byte* dex_file,
size_t length,
const std::string& location,
- Closer* closer);
+ MemMap* mem_map);
- DexFile(const byte* addr, size_t length, const std::string& location, Closer* closer)
+ DexFile(const byte* addr, size_t length, const std::string& location, MemMap* mem_map)
: base_(addr),
length_(length),
location_(location),
- closer_(closer),
+ mem_map_(mem_map),
dex_object_lock_("a dex_object_lock_"),
dex_object_(NULL),
header_(0),
@@ -894,7 +860,7 @@
class_defs_(0) {
CHECK(addr != NULL);
CHECK_GT(length, 0U);
- CHECK(closer != NULL);
+ CHECK(mem_map != NULL);
}
// Top-level initializer that calls other Init methods.
@@ -928,8 +894,8 @@
// path to DexCache::GetLocation when loading from an image.
const std::string location_;
- // Helper object to free the underlying allocation.
- UniquePtr<Closer> closer_;
+ // Manages the underlying memory allocation.
+ UniquePtr<MemMap> mem_map_;
// A cached com.android.dex.Dex instance, possibly NULL. Use GetDexObject.
mutable Mutex dex_object_lock_;
diff --git a/src/dex_file_test.cc b/src/dex_file_test.cc
index 3a9b6f4..ad3b17b 100644
--- a/src/dex_file_test.cc
+++ b/src/dex_file_test.cc
@@ -41,7 +41,8 @@
"AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
TEST_F(DexFileTest, Header) {
- UniquePtr<const DexFile> raw(OpenDexFileBase64(kRawDex, "kRawDex"));
+ ScratchFile tmp;
+ UniquePtr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename()));
ASSERT_TRUE(raw.get() != NULL);
const DexFile::Header& header = raw->GetHeader();
diff --git a/src/exception_test.cc b/src/exception_test.cc
index 2e9cf3f..7acc584 100644
--- a/src/exception_test.cc
+++ b/src/exception_test.cc
@@ -14,76 +14,31 @@
namespace art {
-// package java.lang;
-// import java.io.IOException;
-// class Object {};
-// public class MyClass {
-// int f() throws Exception {
-// try {
-// g(1);
-// } catch (IOException e) {
-// return 1;
-// } catch (Exception e) {
-// return 2;
-// }
-// try {
-// g(2);
-// } catch (IOException e) {
-// return 3;
-// }
-// return 0;
-// }
-// void g(int doThrow) throws Exception {
-// if (doThrow == 1)
-// throw new Exception();
-// else if (doThrow == 2)
-// throw new IOException();
-// }
-// }
-
-static const char kMyClassExceptionHandleDex[] =
- "ZGV4CjAzNQC/bXXtLZJLN1GzLr+ncrvPSl70n8t0yAjgAwAAcAAAAHhWNBIAAAAAAAAAACgDAAAN"
- "AAAAcAAAAAcAAACkAAAAAwAAAMAAAAAAAAAAAAAAAAYAAADkAAAAAgAAABQBAACMAgAAVAEAAD4C"
- "AABGAgAASQIAAGUCAAB8AgAAkwIAAKgCAAC8AgAAygIAAM0CAADRAgAA1AIAANcCAAABAAAAAgAA"
- "AAMAAAAEAAAABQAAAAYAAAAIAAAAAQAAAAAAAAAAAAAACAAAAAYAAAAAAAAACQAAAAYAAAA4AgAA"
- "AgABAAAAAAADAAEAAAAAAAQAAQAAAAAABAAAAAoAAAAEAAIACwAAAAUAAQAAAAAABQAAAAAAAAD/"
- "////AAAAAAcAAAAAAAAACQMAAAAAAAAEAAAAAQAAAAUAAAAAAAAABwAAABgCAAATAwAAAAAAAAEA"
- "AAABAwAAAQABAAAAAADeAgAAAQAAAA4AAAABAAEAAQAAAOMCAAAEAAAAcBAFAAAADgAEAAEAAgAC"
- "AOgCAAAVAAAAEiISERIQbiAEAAMAEiBuIAQAAwASAA8ADQABECj9DQABICj6DQASMCj3AAADAAAA"
- "AwABAAcAAAADAAYAAgICDAMPAQISAAAAAwACAAEAAAD3AgAAEwAAABIQMwIIACIAAwBwEAEAAAAn"
- "ABIgMwIIACIAAgBwEAAAAAAnAA4AAAAAAAAAAAAAAAIAAAAAAAAAAwAAAFQBAAAEAAAAVAEAAAEA"
- "AAAAAAY8aW5pdD4AAUkAGkxkYWx2aWsvYW5ub3RhdGlvbi9UaHJvd3M7ABVMamF2YS9pby9JT0V4"
- "Y2VwdGlvbjsAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwATTGphdmEvbGFuZy9NeUNsYXNzOwASTGph"
- "dmEvbGFuZy9PYmplY3Q7AAxNeUNsYXNzLmphdmEAAVYAAlZJAAFmAAFnAAV2YWx1ZQADAAcOAAQA"
- "Bw4ABwAHLFFOAnYsLR4tIR4AFQEABw48aTxpAAIBAQwcARgDAAABAAWAgATcAgAAAQICgYAE8AID"
- "AIgDAQDgAwAAAA8AAAAAAAAAAQAAAAAAAAABAAAADQAAAHAAAAACAAAABwAAAKQAAAADAAAAAwAA"
- "AMAAAAAFAAAABgAAAOQAAAAGAAAAAgAAABQBAAADEAAAAQAAAFQBAAABIAAABAAAAFwBAAAGIAAA"
- "AQAAABgCAAABEAAAAQAAADgCAAACIAAADQAAAD4CAAADIAAABAAAAN4CAAAEIAAAAQAAAAEDAAAA"
- "IAAAAgAAAAkDAAAAEAAAAQAAACgDAAA=";
-
class ExceptionTest : public CommonTest {
protected:
virtual void SetUp() {
CommonTest::SetUp();
- dex_.reset(OpenDexFileBase64(kMyClassExceptionHandleDex, "kMyClassExceptionHandleDex"));
- ASSERT_TRUE(dex_.get() != NULL);
- const ClassLoader* class_loader = AllocPathClassLoader(dex_.get());
- ASSERT_TRUE(class_loader != NULL);
- my_klass_ = class_linker_->FindClass("Ljava/lang/MyClass;", class_loader);
+ const ClassLoader* class_loader = LoadDex("ExceptionHandle");
+ my_klass_ = class_linker_->FindClass("LExceptionHandle;", class_loader);
ASSERT_TRUE(my_klass_ != NULL);
+
+ dex_ = &Runtime::Current()->GetClassLinker()->FindDexFile(my_klass_->GetDexCache());
+
ByteArray* fake_code = ByteArray::Alloc(12);
ASSERT_TRUE(fake_code != NULL);
IntArray* fake_mapping_data = IntArray::Alloc(2);
ASSERT_TRUE(fake_mapping_data != NULL);
fake_mapping_data->Set(0, 3); // offset 3
fake_mapping_data->Set(1, 3); // maps to dex offset 3
+
method_f_ = my_klass_->FindVirtualMethod("f", "()I");
ASSERT_TRUE(method_f_ != NULL);
method_f_->SetFrameSizeInBytes(kStackAlignment);
method_f_->SetReturnPcOffsetInBytes(kStackAlignment-kPointerSize);
method_f_->SetCodeArray(fake_code, kThumb2);
method_f_->SetMappingTable(fake_mapping_data);
+
method_g_ = my_klass_->FindVirtualMethod("g", "(I)V");
ASSERT_TRUE(method_g_ != NULL);
method_g_->SetFrameSizeInBytes(kStackAlignment);
@@ -92,7 +47,7 @@
method_g_->SetMappingTable(fake_mapping_data);
}
- UniquePtr<const DexFile> dex_;
+ const DexFile* dex_;
Method* method_f_;
Method* method_g_;
@@ -102,7 +57,7 @@
};
TEST_F(ExceptionTest, FindCatchHandler) {
- const DexFile::CodeItem *code_item = dex_->GetCodeItem(method_f_->GetCodeItemOffset());
+ const DexFile::CodeItem* code_item = dex_->GetCodeItem(method_f_->GetCodeItemOffset());
ASSERT_TRUE(code_item != NULL);
@@ -169,16 +124,16 @@
Decode<ObjectArray<StackTraceElement>*>(env, ste_array);
ASSERT_TRUE(trace_array->Get(0) != NULL);
- EXPECT_STREQ("java.lang.MyClass",
+ EXPECT_STREQ("ExceptionHandle",
trace_array->Get(0)->GetDeclaringClass()->ToModifiedUtf8().c_str());
- EXPECT_STREQ("MyClass.java", trace_array->Get(0)->GetFileName()->ToModifiedUtf8().c_str());
+ EXPECT_STREQ("ExceptionHandle.java", trace_array->Get(0)->GetFileName()->ToModifiedUtf8().c_str());
EXPECT_STREQ("g", trace_array->Get(0)->GetMethodName()->ToModifiedUtf8().c_str());
EXPECT_EQ(22, trace_array->Get(0)->GetLineNumber());
ASSERT_TRUE(trace_array->Get(1) != NULL);
- EXPECT_STREQ("java.lang.MyClass",
+ EXPECT_STREQ("ExceptionHandle",
trace_array->Get(1)->GetDeclaringClass()->ToModifiedUtf8().c_str());
- EXPECT_STREQ("MyClass.java", trace_array->Get(1)->GetFileName()->ToModifiedUtf8().c_str());
+ EXPECT_STREQ("ExceptionHandle.java", trace_array->Get(1)->GetFileName()->ToModifiedUtf8().c_str());
EXPECT_STREQ("f", trace_array->Get(1)->GetMethodName()->ToModifiedUtf8().c_str());
EXPECT_EQ(7, trace_array->Get(1)->GetLineNumber());
}
diff --git a/src/stack_walk.cc b/src/stack_walk.cc
index bc7b3a3..2c29e75 100644
--- a/src/stack_walk.cc
+++ b/src/stack_walk.cc
@@ -6,7 +6,6 @@
#include "class_linker.h"
#include "common_test.h"
#include "dex_verifier.h"
-// #include "heap.h"
#include "object.h"
#include "jni.h"