Allow MemMap to support empty map requests
Discovered trying to use ZipEntry::ExtractToMemMap on an empty preloaded-classes.
Bug: 8659045
Change-Id: Icfbbe6b313e2d1ee708b44a8d8d354d6203fd669
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index ad33365..6a73fc0 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -39,6 +39,7 @@
runtime/indirect_reference_table_test.cc \
runtime/intern_table_test.cc \
runtime/jni_internal_test.cc \
+ runtime/mem_map_test.cc \
runtime/mirror/dex_cache_test.cc \
runtime/mirror/object_test.cc \
runtime/oat/utils/arm/managed_register_arm_test.cc \
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc
index 619b73c..9a34610 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -68,7 +68,9 @@
#endif
MemMap* MemMap::MapAnonymous(const char* name, byte* addr, size_t byte_count, int prot) {
- CHECK_NE(0U, byte_count);
+ if (byte_count == 0) {
+ return new MemMap(name, NULL, 0, NULL, 0, prot);
+ }
size_t page_aligned_byte_count = RoundUp(byte_count, kPageSize);
CheckMapRequest(addr, page_aligned_byte_count);
@@ -102,9 +104,11 @@
MemMap* MemMap::MapFileAtAddress(byte* addr, size_t byte_count,
int prot, int flags, int fd, off_t start, bool reuse) {
- CHECK_NE(0U, byte_count);
CHECK_NE(0, prot);
CHECK_NE(0, flags & (MAP_SHARED | MAP_PRIVATE));
+ if (byte_count == 0) {
+ return new MemMap("file", NULL, 0, NULL, 0, prot);
+ }
// Adjust 'offset' to be page-aligned as required by mmap.
int page_offset = start % kPageSize;
off_t page_aligned_offset = start - page_offset;
@@ -153,10 +157,15 @@
size_t base_size, int prot)
: name_(name), begin_(begin), size_(size), base_begin_(base_begin), base_size_(base_size),
prot_(prot) {
- CHECK(begin_ != NULL);
- CHECK_NE(size_, 0U);
- CHECK(base_begin_ != NULL);
- CHECK_NE(base_size_, 0U);
+ if (size_ == 0) {
+ CHECK(begin_ == NULL);
+ CHECK(base_begin_ == NULL);
+ CHECK_EQ(base_size_, 0U);
+ } else {
+ CHECK(begin_ != NULL);
+ CHECK(base_begin_ != NULL);
+ CHECK_NE(base_size_, 0U);
+ }
};
void MemMap::UnMapAtEnd(byte* new_end) {
diff --git a/runtime/mem_map_test.cc b/runtime/mem_map_test.cc
new file mode 100644
index 0000000..dade01b
--- /dev/null
+++ b/runtime/mem_map_test.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 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 "mem_map.h"
+
+#include "UniquePtr.h"
+#include "gtest/gtest.h"
+
+namespace art {
+
+class MemMapTest : public testing::Test {};
+
+TEST_F(MemMapTest, MapAnonymousEmpty) {
+ UniquePtr<MemMap> map(MemMap::MapAnonymous("MapAnonymousEmpty",
+ NULL,
+ 0,
+ PROT_READ));
+ ASSERT_TRUE(map.get() != NULL);
+}
+
+} // namespace art