Move .oat files to ELF format

Generates .oat in ELF file format using MCLinker
- Uses MCLinker IRBuilder to create a synthetic .o from OatWriter output.
- Uses new ElfFile for prelinking to support art image optimizations.

Adapted OatFile to load using dlopen, ElfFile, or memory, removing raw MemMap mechanism.

Changed image code to not assume oat data will be immediately after
image to allow space for ELF headers.

Passes test-art and works with installd.

Change-Id: Idc026eddb5de93f4b97490c405f3ed7b39589749
diff --git a/src/elf_writer_test.cc b/src/elf_writer_test.cc
new file mode 100644
index 0000000..57d7e14
--- /dev/null
+++ b/src/elf_writer_test.cc
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011 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 "common_test.h"
+
+#include "oat.h"
+#include "elf_file.h"
+
+namespace art {
+
+class ElfWriterTest : public CommonTest {
+
+ protected:
+  virtual void SetUp() {
+    ReserveImageSpace();
+    CommonTest::SetUp();
+  }
+};
+
+#define EXPECT_ELF_FILE_ADDRESS(ef, value, name) \
+  EXPECT_EQ(value, reinterpret_cast<void*>(ef->FindSymbolAddress(llvm::ELF::SHT_SYMTAB, name))); \
+  EXPECT_EQ(value, reinterpret_cast<void*>(ef->FindSymbolAddress(llvm::ELF::SHT_DYNSYM, name))); \
+  EXPECT_EQ(value, ef->FindDynamicSymbolAddress(name)); \
+
+TEST_F(ElfWriterTest, dlsym) {
+  std::string elf_filename;
+  if (IsHost()) {
+    const char* host_dir = getenv("ANDROID_HOST_OUT");
+    CHECK(host_dir != NULL);
+    elf_filename = StringPrintf("%s/framework/core.oat", host_dir);
+  } else {
+    elf_filename = "/data/art-test/core.oat";
+  }
+  LOG(INFO) << "elf_filename=" << elf_filename;
+
+  UnreserveImageSpace();
+  void* dl_oat_so = dlopen(elf_filename.c_str(), RTLD_NOW);
+  ASSERT_TRUE(dl_oat_so != NULL) << dlerror();
+  void* dl_oatdata = dlsym(dl_oat_so, "oatdata");
+  ASSERT_TRUE(dl_oatdata != NULL);
+
+  OatHeader* dl_oat_header = reinterpret_cast<OatHeader*>(dl_oatdata);
+  ASSERT_TRUE(dl_oat_header->IsValid());
+  void* dl_oatexec = dlsym(dl_oat_so, "oatexec");
+  ASSERT_TRUE(dl_oatexec != NULL);
+  ASSERT_LT(dl_oatdata, dl_oatexec);
+
+  void* dl_oatlastword = dlsym(dl_oat_so, "oatlastword");
+  ASSERT_TRUE(dl_oatlastword != NULL);
+  ASSERT_LT(dl_oatexec, dl_oatlastword);
+
+  ASSERT_EQ(0, dlclose(dl_oat_so));
+
+  UniquePtr<File> file(OS::OpenFile(elf_filename.c_str(), false));
+  ASSERT_TRUE(file.get() != NULL);
+  {
+    UniquePtr<ElfFile> ef(ElfFile::Open(file.get(), false, false));
+    CHECK(ef.get() != NULL);
+    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatdata, "oatdata");
+    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatexec, "oatexec");
+    EXPECT_ELF_FILE_ADDRESS(ef, dl_oatlastword, "oatlastword");
+  }
+  {
+    UniquePtr<ElfFile> ef(ElfFile::Open(file.get(), false, true));
+    CHECK(ef.get() != NULL);
+    ef->Load();
+    EXPECT_EQ(dl_oatdata, ef->FindDynamicSymbolAddress("oatdata"));
+    EXPECT_EQ(dl_oatexec, ef->FindDynamicSymbolAddress("oatexec"));
+    EXPECT_EQ(dl_oatlastword, ef->FindDynamicSymbolAddress("oatlastword"));
+  }
+}
+
+}  // namespace art