Adding oat_process

- Added oat_process, a version of app_process use to launch frameworks apps
- Added liboat_runtime, a version of libandroid_runtime that uses art instead of dvm
  This is just a special makefile, frameworks/base/core/jni code is used for source
- Added support for build a boot.oat with the full BOOTCLASSPATH
  The older smaller boat.oat is now core.oat
- Added mem_map code for making sure a requested memory region is available
  Moved mem_map code to cc file to make easier to debug with smaller rebuild
- Moved oat base address to 0x6000000 as a work around to host addres conflict
- Added -Xms and -Xmx options to dex2oat to allow build specific memory options
- Fixed miranda method initialization problem found compiling full bootclasspath
- Made compiler.cc tolerant of verification errors found compiling full bootclasspath
- Bumped arena block alloc warning to avoid noise when compiling full bootclasspath
- Marked implicit GC unimplemented to fail fast
- Added --output argument to oatdump
- Made many object asserts tolerate access in IsErroneous state
  now that verifier is failing validation of some classes during compilation
- Made runtime tolerate unknown access as short term solution for oat_process
- Workaround SSA issue to restore full bootclasspath compilation
- Added test-art-target-processs to excercise oat_process with "am"
  "am" found bug where class_linker was using Method::GetClass and not ::GetDeclaringClass

Change-Id: I1a645a142b163e06bab9e72eb094ae1f1dbfbd97
diff --git a/src/mem_map.cc b/src/mem_map.cc
new file mode 100644
index 0000000..e44a894
--- /dev/null
+++ b/src/mem_map.cc
@@ -0,0 +1,163 @@
+#include "mem_map.h"
+
+#include <sys/mman.h>
+
+#include "utils.h"
+
+/*
+ * Copyright (C) 2008 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 <sys/mman.h>
+
+namespace art {
+
+size_t ParseHex(const std::string& string) {
+  CHECK_EQ(8U, string.size());
+  const char* str = string.c_str();
+  char* end;
+  size_t value = strtoul(str, &end, 16);
+  CHECK(end != str) << "Failed to parse hexadecimal value from " << string;
+  CHECK(*end == '\0') << "Failed to parse hexadecimal value from " << string;
+  return value;
+}
+
+void CheckMapRequest(byte* addr, size_t length) {
+#ifndef NDEBUG
+  if (addr == NULL) {
+    return;
+  }
+  size_t base = reinterpret_cast<size_t>(addr);
+  size_t limit = base + length;
+
+  std::string maps;
+  bool read = ReadFileToString("/proc/self/maps", &maps);
+  if (!read) {
+    PLOG(FATAL) << "Failed to read /proc/self/maps";
+  }
+  // Quick and dirty parse of output like shown below. We only focus
+  // on grabbing the two 32-bit hex values at the start of each line
+  // and will fail on wider addresses found on 64-bit systems.
+
+  // 00008000-0001f000 r-xp 00000000 b3:01 273        /system/bin/toolbox
+  // 0001f000-00021000 rw-p 00017000 b3:01 273        /system/bin/toolbox
+  // 00021000-00029000 rw-p 00000000 00:00 0          [heap]
+  // 40011000-40053000 r-xp 00000000 b3:01 1050       /system/lib/libc.so
+  // 40053000-40056000 rw-p 00042000 b3:01 1050       /system/lib/libc.so
+  // 40056000-40061000 rw-p 00000000 00:00 0
+  // 40061000-40063000 r-xp 00000000 b3:01 1107       /system/lib/libusbhost.so
+  // 40063000-40064000 rw-p 00002000 b3:01 1107       /system/lib/libusbhost.so
+  // 4009d000-400a0000 r-xp 00000000 b3:01 1022       /system/lib/liblog.so
+  // 400a0000-400a1000 rw-p 00003000 b3:01 1022       /system/lib/liblog.so
+  // 400b7000-400cc000 r-xp 00000000 b3:01 932        /system/lib/libm.so
+  // 400cc000-400cd000 rw-p 00015000 b3:01 932        /system/lib/libm.so
+  // 400cf000-400d0000 r--p 00000000 00:00 0
+  // 400e4000-400ec000 r--s 00000000 00:0b 388        /dev/__properties__ (deleted)
+  // 400ec000-400fa000 r-xp 00000000 b3:01 1101       /system/lib/libcutils.so
+  // 400fa000-400fb000 rw-p 0000e000 b3:01 1101       /system/lib/libcutils.so
+  // 400fb000-4010a000 rw-p 00000000 00:00 0
+  // 4010d000-4010e000 r-xp 00000000 b3:01 929        /system/lib/libstdc++.so
+  // 4010e000-4010f000 rw-p 00001000 b3:01 929        /system/lib/libstdc++.so
+  // b0001000-b0009000 r-xp 00001000 b3:01 1098       /system/bin/linker
+  // b0009000-b000a000 rw-p 00009000 b3:01 1098       /system/bin/linker
+  // b000a000-b0015000 rw-p 00000000 00:00 0
+  // bee35000-bee56000 rw-p 00000000 00:00 0          [stack]
+  // ffff0000-ffff1000 r-xp 00000000 00:00 0          [vectors]
+
+  for (size_t i = 0; i < maps.size(); i++) {
+    size_t remaining = maps.size() - i;
+    if (remaining < 8+1+8) {  // 00008000-0001f000
+      LOG(FATAL) << "Failed to parse at pos " << i << "\n" << maps;
+    }
+    std::string start_str = maps.substr(i, 8);
+    std::string end_str = maps.substr(i+1+8, 8);
+    uint32_t start = ParseHex(start_str);
+    uint32_t end = ParseHex(end_str);
+    CHECK(!(base >= start && base < end)
+          && !(limit >= start && limit < end)
+          && !(base <= start && limit > end))
+        << StringPrintf("Requested region %08x-%08x overlaps with existing map %08x-%08x\n",
+                        base, limit, start, end)
+        << maps;
+    i += 8+1+8;
+    i = maps.find('\n', i);
+    CHECK(i != std::string::npos) << "Failed to find newline from pos " << i << "\n" << maps;
+  }
+#endif
+}
+
+MemMap* MemMap::Map(byte* addr, size_t length, int prot) {
+  CHECK_NE(0U, length);
+  CHECK_NE(0, prot);
+  size_t page_aligned_size = RoundUp(length, kPageSize);
+  CheckMapRequest(addr, page_aligned_size);
+  byte* actual = reinterpret_cast<byte*>(mmap(addr,
+                                              page_aligned_size,
+                                              prot,
+                                              MAP_PRIVATE | MAP_ANONYMOUS,
+                                              -1,
+                                              0));
+  if (actual == MAP_FAILED) {
+    PLOG(ERROR) << "mmap failed";
+    return NULL;
+  }
+  return new MemMap(actual, length, actual, page_aligned_size);
+}
+
+MemMap* MemMap::Map(byte* addr, size_t length, int prot, int flags, int fd, off_t start) {
+  CHECK_NE(0U, length);
+  CHECK_NE(0, prot);
+  CHECK_NE(0, flags & (MAP_SHARED | MAP_PRIVATE));
+  // adjust to be page-aligned
+  int page_offset = start % kPageSize;
+  off_t page_aligned_offset = start - page_offset;
+  size_t page_aligned_size = RoundUp(length + page_offset, kPageSize);
+  CheckMapRequest(addr, page_aligned_size);
+  byte* actual = reinterpret_cast<byte*>(mmap(addr,
+                                              page_aligned_size,
+                                              prot,
+                                              flags,
+                                              fd,
+                                              page_aligned_offset));
+  if (actual == MAP_FAILED) {
+    PLOG(ERROR) << "mmap failed";
+    return NULL;
+  }
+  return new MemMap(actual + page_offset, length, actual, page_aligned_size);
+}
+
+MemMap::~MemMap() {
+  if (base_addr_ == NULL && base_length_ == 0) {
+    return;
+  }
+  int result = munmap(base_addr_, base_length_);
+  base_addr_ = NULL;
+  base_length_ = 0;
+  if (result == -1) {
+    PLOG(FATAL) << "munmap failed";
+  }
+}
+
+MemMap::MemMap(byte* addr, size_t length, void* base_addr, size_t base_length)
+    : addr_(addr), length_(length), base_addr_(base_addr), base_length_(base_length) {
+  CHECK(addr_ != NULL);
+  CHECK(length_ != 0);
+  CHECK(base_addr_ != NULL);
+  CHECK(base_length_ != 0);
+};
+
+}  // namespace art