diff options
author | 2011-10-03 11:24:05 -0700 | |
---|---|---|
committer | 2011-10-03 11:24:05 -0700 | |
commit | 33f741eefef8f8012f6c190b39355f2e0430d535 (patch) | |
tree | 8d17953423f87d6fec38404dd503b6bfad9ac474 | |
parent | 1afef11c4cfb0ac37db7aba183bf71f938af2520 (diff) |
Remove opening of DexFile from pointer
Change-Id: I158e75e9e72f1dcc579742ff08c80d3f857852b3
-rw-r--r-- | build/Android.common.mk | 1 | ||||
-rw-r--r-- | src/common_test.h | 15 | ||||
-rw-r--r-- | src/dex_file.cc | 41 | ||||
-rw-r--r-- | src/dex_file.h | 48 | ||||
-rw-r--r-- | src/dex_file_test.cc | 3 | ||||
-rw-r--r-- | src/exception_test.cc | 71 | ||||
-rw-r--r-- | src/stack_walk.cc | 1 | ||||
-rw-r--r-- | test/ExceptionHandle/ExceptionHandle.java | 27 |
8 files changed, 72 insertions, 135 deletions
diff --git a/build/Android.common.mk b/build/Android.common.mk index 481fbc051e..69580ccd89 100644 --- a/build/Android.common.mk +++ b/build/Android.common.mk @@ -211,6 +211,7 @@ TEST_DEX_DIRECTORIES := \ AbstractMethod \ AllFields \ CreateMethodDescriptor \ + ExceptionHandle \ ExceptionTest \ Fibonacci \ HelloWorld \ diff --git a/src/common_test.h b/src/common_test.h index 8491dbbbb4..a7c5ea8c09 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 @@ namespace art { 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 d437a3fc9c..b4cf83793c 100644 --- a/src/dex_file.cc +++ b/src/dex_file.cc @@ -71,29 +71,11 @@ const DexFile* DexFile::Open(const std::string& filename, } 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 @@ const DexFile* DexFile::OpenFile(const std::string& filename, 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 @@ const DexFile* DexFile::OpenZip(const std::string& filename, // 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 e313d74bdb..cb979aee99 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 @@ class DexFile { 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 @@ class DexFile { 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 DexFile { 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 @@ class DexFile { // 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 3a9b6f4dc5..ad3b17b770 100644 --- a/src/dex_file_test.cc +++ b/src/dex_file_test.cc @@ -41,7 +41,8 @@ static const char kRawDex[] = "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 2e9cf3feb6..7acc584187 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 @@ class ExceptionTest : public CommonTest { method_g_->SetMappingTable(fake_mapping_data); } - UniquePtr<const DexFile> dex_; + const DexFile* dex_; Method* method_f_; Method* method_g_; @@ -102,7 +57,7 @@ class ExceptionTest : public CommonTest { }; 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 @@ TEST_F(ExceptionTest, StackTraceElement) { 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 bc7b3a3b24..2c29e757aa 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" diff --git a/test/ExceptionHandle/ExceptionHandle.java b/test/ExceptionHandle/ExceptionHandle.java new file mode 100644 index 0000000000..94c6f5b8eb --- /dev/null +++ b/test/ExceptionHandle/ExceptionHandle.java @@ -0,0 +1,27 @@ +// Copyright 2011 Google Inc. All Rights Reserved. +import java.io.IOException; + +public class ExceptionHandle { + 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(); + } + } +} |