Introduce ObjectLoader and RSExecutable.

ObjectLoader loads an object file into memory.

ObjectLoaderImpl defines a set of format-independent interfaces
that a object file format loader has to provide.

ELFObjectLoaderImpl is a subclass of ObjectLoaderImpl and can be used
to load an ELF relocatable object built based on librsloader. It
directly uses the C++ APIs provided by librsloader instead of using
wrapped C APIs defined in librsloader.h

RSExecutable holds the build results of a RSScript.
diff --git a/lib/ExecutionEngine/ELFObjectLoaderImpl.cpp b/lib/ExecutionEngine/ELFObjectLoaderImpl.cpp
new file mode 100644
index 0000000..01f613e
--- /dev/null
+++ b/lib/ExecutionEngine/ELFObjectLoaderImpl.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2012, 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 "ELFObjectLoaderImpl.h"
+
+#include <llvm/Support/ELF.h>
+
+// The following files are included from librsloader.
+#include "ELFObject.h"
+#include "ELFSectionSymTab.h"
+#include "ELFSymbol.h"
+#include "utils/serialize.h"
+
+#include "DebugHelper.h"
+#include "SymbolResolverInterface.h"
+
+using namespace bcc;
+
+bool ELFObjectLoaderImpl::load(const void *pMem, size_t pMemSize) {
+  ArchiveReaderLE reader(reinterpret_cast<const unsigned char *>(pMem),
+                         pMemSize);
+
+  mObject = ELFObject<32>::read(reader);
+  if (mObject == NULL) {
+    ALOGE("Unable to load the ELF object!");
+    return false;
+  }
+
+  // Retrive the pointer to the symbol table.
+  mSymTab = static_cast<ELFSectionSymTab<32> *>(
+                mObject->getSectionByName(".symtab"));
+  if (mSymTab == NULL) {
+    ALOGW("Object doesn't contain any symbol table.");
+  }
+
+  return true;
+}
+
+bool ELFObjectLoaderImpl::relocate(SymbolResolverInterface &pResolver) {
+  mObject->relocate(SymbolResolverInterface::LookupFunction, &pResolver);
+
+  if (mObject->getMissingSymbols()) {
+    ALOGE("Some symbols are found to be undefined during relocation!");
+    return false;
+  }
+
+  return true;
+}
+
+bool ELFObjectLoaderImpl::prepareDebugImage(void *pDebugImg,
+                                            size_t pDebugImgSize) {
+  // Update the value of sh_addr in pDebugImg to its corresponding section in
+  // the mObject.
+  llvm::ELF::Elf32_Ehdr *elf_header =
+      reinterpret_cast<llvm::ELF::Elf32_Ehdr *>(pDebugImg);
+
+  if (elf_header->e_shoff > pDebugImgSize) {
+    ALOGE("Invalid section header table offset found! (e_shoff = %d)",
+          elf_header->e_shoff);
+    return false;
+  }
+
+  if ((elf_header->e_shoff +
+       sizeof(llvm::ELF::Elf32_Shdr) * elf_header->e_shnum) > pDebugImgSize) {
+    ALOGE("Invalid image supplied (debug image doesn't contain all the section"
+          "header or corrupted image)! (e_shoff = %d, e_shnum = %d)",
+          elf_header->e_shoff, elf_header->e_shnum);
+    return false;
+  }
+
+  llvm::ELF::Elf32_Shdr *section_header_table =
+      reinterpret_cast<llvm::ELF::Elf32_Shdr *>(
+          reinterpret_cast<uint8_t*>(pDebugImg) + elf_header->e_shoff);
+
+  for (unsigned i = 0; i < elf_header->e_shnum; i++) {
+    if (section_header_table[i].sh_flags & llvm::ELF::SHF_ALLOC) {
+      ELFSectionBits<32> *section =
+          static_cast<ELFSectionBits<32> *>(mObject->getSectionByIndex(i));
+      if (section != NULL) {
+        section_header_table[i].sh_addr =
+            reinterpret_cast<llvm::ELF::Elf32_Addr>(section->getBuffer());
+      }
+    }
+  }
+
+  return true;
+}
+
+void *ELFObjectLoaderImpl::getSymbolAddress(const char *pName) const {
+  if (mSymTab == NULL) {
+    return NULL;
+  }
+
+  ELFSymbol<32> *symbol = mSymTab->getByName(pName);
+  if (symbol == NULL) {
+    ALOGV("Request symbol '%s' is not found in the object!", pName);
+    return NULL;
+  }
+
+  return symbol->getAddress(mObject->getHeader()->getMachine(),
+                            /* autoAlloc */false);
+}
+
+ELFObjectLoaderImpl::~ELFObjectLoaderImpl() {
+  delete mObject;
+  return;
+}