Add support for .bss section in oat files.

Change-Id: I779b80b8139d9afdc28373f8c68edff5df7726ce
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 739d62c..356e3d2 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -52,17 +52,7 @@
   CHECK(has_section);
   oat_file->begin_ = elf_file->Begin() + offset;
   oat_file->end_ = elf_file->Begin() + size + offset;
-  return oat_file->Setup(error_msg) ? oat_file.release() : nullptr;
-}
-
-OatFile* OatFile::OpenMemory(std::vector<uint8_t>& oat_contents,
-                             const std::string& location,
-                             std::string* error_msg) {
-  CHECK(!oat_contents.empty()) << location;
-  CheckLocation(location);
-  std::unique_ptr<OatFile> oat_file(new OatFile(location, false));
-  oat_file->begin_ = &oat_contents[0];
-  oat_file->end_ = &oat_contents[oat_contents.size()];
+  // Ignore the optional .bss section when opening non-executable.
   return oat_file->Setup(error_msg) ? oat_file.release() : nullptr;
 }
 
@@ -108,18 +98,6 @@
   return OpenElfFile(file, location, nullptr, nullptr, false, false, error_msg);
 }
 
-OatFile* OatFile::OpenDlopen(const std::string& elf_filename,
-                             const std::string& location,
-                             uint8_t* requested_base,
-                             std::string* error_msg) {
-  std::unique_ptr<OatFile> oat_file(new OatFile(location, true));
-  bool success = oat_file->Dlopen(elf_filename, requested_base, error_msg);
-  if (!success) {
-    return nullptr;
-  }
-  return oat_file.release();
-}
-
 OatFile* OatFile::OpenElfFile(File* file,
                               const std::string& location,
                               uint8_t* requested_base,
@@ -138,8 +116,8 @@
 }
 
 OatFile::OatFile(const std::string& location, bool is_executable)
-    : location_(location), begin_(NULL), end_(NULL), is_executable_(is_executable),
-      dlopen_handle_(NULL),
+    : location_(location), begin_(NULL), end_(NULL), bss_begin_(nullptr), bss_end_(nullptr),
+      is_executable_(is_executable), dlopen_handle_(NULL),
       secondary_lookup_lock_("OatFile secondary lookup lock", kOatFileSecondaryLookupLock) {
   CHECK(!location_.empty());
 }
@@ -151,43 +129,6 @@
   }
 }
 
-bool OatFile::Dlopen(const std::string& elf_filename, uint8_t* requested_base,
-                     std::string* error_msg) {
-  char* absolute_path = realpath(elf_filename.c_str(), NULL);
-  if (absolute_path == NULL) {
-    *error_msg = StringPrintf("Failed to find absolute path for '%s'", elf_filename.c_str());
-    return false;
-  }
-  dlopen_handle_ = dlopen(absolute_path, RTLD_NOW);
-  free(absolute_path);
-  if (dlopen_handle_ == NULL) {
-    *error_msg = StringPrintf("Failed to dlopen '%s': %s", elf_filename.c_str(), dlerror());
-    return false;
-  }
-  begin_ = reinterpret_cast<uint8_t*>(dlsym(dlopen_handle_, "oatdata"));
-  if (begin_ == NULL) {
-    *error_msg = StringPrintf("Failed to find oatdata symbol in '%s': %s", elf_filename.c_str(),
-                              dlerror());
-    return false;
-  }
-  if (requested_base != NULL && begin_ != requested_base) {
-    PrintFileToLog("/proc/self/maps", LogSeverity::WARNING);
-    *error_msg = StringPrintf("Failed to find oatdata symbol at expected address: "
-                              "oatdata=%p != expected=%p. See process maps in the log.",
-                              begin_, requested_base);
-    return false;
-  }
-  end_ = reinterpret_cast<uint8_t*>(dlsym(dlopen_handle_, "oatlastword"));
-  if (end_ == NULL) {
-    *error_msg = StringPrintf("Failed to find oatlastword symbol in '%s': %s", elf_filename.c_str(),
-                              dlerror());
-    return false;
-  }
-  // Readjust to be non-inclusive upper bound.
-  end_ += sizeof(uint32_t);
-  return Setup(error_msg);
-}
-
 bool OatFile::ElfFileOpen(File* file, uint8_t* requested_base, uint8_t* oat_file_begin,
                           bool writable, bool executable,
                           std::string* error_msg) {
@@ -222,6 +163,23 @@
   }
   // Readjust to be non-inclusive upper bound.
   end_ += sizeof(uint32_t);
+
+  bss_begin_ = elf_file_->FindDynamicSymbolAddress("oatbss");
+  if (bss_begin_ == nullptr) {
+    // No .bss section. Clear dlerror().
+    bss_end_ = nullptr;
+    dlerror();
+  } else {
+    bss_end_ = elf_file_->FindDynamicSymbolAddress("oatbsslastword");
+    if (bss_end_ == nullptr) {
+      *error_msg = StringPrintf("Failed to find oatbasslastword symbol in '%s'",
+                                file->GetPath().c_str());
+      return false;
+    }
+    // Readjust to be non-inclusive upper bound.
+    bss_end_ += sizeof(uint32_t);
+  }
+
   return Setup(error_msg);
 }
 
@@ -363,6 +321,14 @@
   return end_;
 }
 
+const uint8_t* OatFile::BssBegin() const {
+  return bss_begin_;
+}
+
+const uint8_t* OatFile::BssEnd() const {
+  return bss_end_;
+}
+
 const OatFile::OatDexFile* OatFile::GetOatDexFile(const char* dex_location,
                                                   const uint32_t* dex_location_checksum,
                                                   bool warn_if_not_found) const {