diff --git a/libdexfile/external/dex_file_ext.cc b/libdexfile/external/dex_file_ext.cc
new file mode 100644
index 0000000..3c193f4
--- /dev/null
+++ b/libdexfile/external/dex_file_ext.cc
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2018 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 <inttypes.h>
+#include <stdint.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <cerrno>
+#include <cstring>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <android-base/mapped_file.h>
+#include <android-base/stringprintf.h>
+
+#include <dex/class_accessor-inl.h>
+#include <dex/code_item_accessors-inl.h>
+#include <dex/dex_file-inl.h>
+#include <dex/dex_file_loader.h>
+
+#include "art_api/ext_dex_file.h"
+
+extern "C" class ExtDexFileString {
+ public:
+  const std::string str_;
+};
+
+namespace art {
+namespace {
+
+const ExtDexFileString empty_string{""};
+
+struct MethodCacheEntry {
+  int32_t offset;  // Offset relative to the start of the dex file header.
+  int32_t len;
+  int32_t index;  // Method index.
+  std::string name;  // Method name. Not filled in for all cache entries.
+};
+
+class MappedFileContainer : public DexFileContainer {
+ public:
+  explicit MappedFileContainer(std::unique_ptr<android::base::MappedFile>&& map)
+      : map_(std::move(map)) {}
+  ~MappedFileContainer() override {}
+  int GetPermissions() override { return 0; }
+  bool IsReadOnly() override { return true; }
+  bool EnableWrite() override { return false; }
+  bool DisableWrite() override { return false; }
+
+ private:
+  std::unique_ptr<android::base::MappedFile> map_;
+  DISALLOW_COPY_AND_ASSIGN(MappedFileContainer);
+};
+
+}  // namespace
+}  // namespace art
+
+extern "C" {
+
+const ExtDexFileString* ExtDexFileMakeString(const char* str) {
+  if (str[0] == '\0') {
+    return &art::empty_string;
+  }
+  return new ExtDexFileString{str};
+}
+
+const char* ExtDexFileGetString(const ExtDexFileString* ext_string, /*out*/ size_t* size) {
+  DCHECK(ext_string != nullptr);
+  *size = ext_string->str_.size();
+  return ext_string->str_.data();
+}
+
+void ExtDexFileFreeString(const ExtDexFileString* ext_string) {
+  DCHECK(ext_string != nullptr);
+  if (ext_string != &art::empty_string) {
+    delete (ext_string);
+  }
+}
+
+// Wraps DexFile to add the caching needed by the external interface. This is
+// what gets passed over as ExtDexFile*.
+class ExtDexFile {
+  // Method cache for GetMethodInfoForOffset. This is populated as we iterate
+  // sequentially through the class defs. MethodCacheEntry.name is only set for
+  // methods returned by GetMethodInfoForOffset.
+  std::map<int32_t, art::MethodCacheEntry> method_cache_;
+
+  // Index of first class def for which method_cache_ isn't complete.
+  uint32_t class_def_index_ = 0;
+
+ public:
+  std::unique_ptr<const art::DexFile> dex_file_;
+  explicit ExtDexFile(std::unique_ptr<const art::DexFile>&& dex_file)
+      : dex_file_(std::move(dex_file)) {}
+
+  art::MethodCacheEntry* GetMethodCacheEntryForOffset(int64_t dex_offset) {
+    // First look in the method cache.
+    auto it = method_cache_.upper_bound(dex_offset);
+    if (it != method_cache_.end() && dex_offset >= it->second.offset) {
+      return &it->second;
+    }
+
+    for (; class_def_index_ < dex_file_->NumClassDefs(); class_def_index_++) {
+      art::ClassAccessor accessor(*dex_file_, class_def_index_);
+
+      for (const art::ClassAccessor::Method& method : accessor.GetMethods()) {
+        art::CodeItemInstructionAccessor code = method.GetInstructions();
+        if (!code.HasCodeItem()) {
+          continue;
+        }
+
+        int32_t offset = reinterpret_cast<const uint8_t*>(code.Insns()) - dex_file_->Begin();
+        int32_t len = code.InsnsSizeInBytes();
+        int32_t index = method.GetIndex();
+        auto res =
+            method_cache_.emplace(offset + len, art::MethodCacheEntry{offset, len, index, ""});
+        if (offset <= dex_offset && dex_offset < offset + len) {
+          return &res.first->second;
+        }
+      }
+    }
+
+    return nullptr;
+  }
+
+  const std::string& GetMethodName(art::MethodCacheEntry& entry) {
+    if (entry.name.empty()) {
+      entry.name = dex_file_->PrettyMethod(entry.index, false);
+    }
+    return entry.name;
+  }
+};
+
+int ExtDexFileOpenFromMemory(const void* addr,
+                             /*inout*/ size_t* size,
+                             const char* location,
+                             /*out*/ const ExtDexFileString** ext_error_msg,
+                             /*out*/ ExtDexFile** ext_dex_file) {
+  if (*size < sizeof(art::DexFile::Header)) {
+    *size = sizeof(art::DexFile::Header);
+    *ext_error_msg = nullptr;
+    return false;
+  }
+
+  const art::DexFile::Header* header = reinterpret_cast<const art::DexFile::Header*>(addr);
+  uint32_t file_size = header->file_size_;
+  if (art::CompactDexFile::IsMagicValid(header->magic_)) {
+    // Compact dex files store the data section separately so that it can be shared.
+    // Therefore we need to extend the read memory range to include it.
+    // TODO: This might be wasteful as we might read data in between as well.
+    //       In practice, this should be fine, as such sharing only happens on disk.
+    uint32_t computed_file_size;
+    if (__builtin_add_overflow(header->data_off_, header->data_size_, &computed_file_size)) {
+      *ext_error_msg = new ExtDexFileString{
+          android::base::StringPrintf("Corrupt CompactDexFile header in '%s'", location)};
+      return false;
+    }
+    if (computed_file_size > file_size) {
+      file_size = computed_file_size;
+    }
+  } else if (!art::StandardDexFile::IsMagicValid(header->magic_)) {
+    *ext_error_msg = new ExtDexFileString{
+        android::base::StringPrintf("Unrecognized dex file header in '%s'", location)};
+    return false;
+  }
+
+  if (*size < file_size) {
+    *size = file_size;
+    *ext_error_msg = nullptr;
+    return false;
+  }
+
+  std::string loc_str(location);
+  art::DexFileLoader loader;
+  std::string error_msg;
+  std::unique_ptr<const art::DexFile> dex_file = loader.Open(static_cast<const uint8_t*>(addr),
+                                                             *size,
+                                                             loc_str,
+                                                             header->checksum_,
+                                                             /*oat_dex_file=*/nullptr,
+                                                             /*verify=*/false,
+                                                             /*verify_checksum=*/false,
+                                                             &error_msg);
+  if (dex_file == nullptr) {
+    *ext_error_msg = new ExtDexFileString{std::move(error_msg)};
+    return false;
+  }
+
+  *ext_dex_file = new ExtDexFile(std::move(dex_file));
+  return true;
+}
+
+int ExtDexFileOpenFromFd(int fd,
+                         off_t offset,
+                         const char* location,
+                         /*out*/ const ExtDexFileString** ext_error_msg,
+                         /*out*/ ExtDexFile** ext_dex_file) {
+  size_t length;
+  {
+    struct stat sbuf;
+    std::memset(&sbuf, 0, sizeof(sbuf));
+    if (fstat(fd, &sbuf) == -1) {
+      *ext_error_msg = new ExtDexFileString{
+          android::base::StringPrintf("fstat '%s' failed: %s", location, std::strerror(errno))};
+      return false;
+    }
+    if (S_ISDIR(sbuf.st_mode)) {
+      *ext_error_msg = new ExtDexFileString{
+          android::base::StringPrintf("Attempt to mmap directory '%s'", location)};
+      return false;
+    }
+    length = sbuf.st_size;
+  }
+
+  if (length < offset + sizeof(art::DexFile::Header)) {
+    *ext_error_msg = new ExtDexFileString{android::base::StringPrintf(
+        "Offset %" PRId64 " too large for '%s' of size %zu", int64_t{offset}, location, length)};
+    return false;
+  }
+
+  // Cannot use MemMap in libartbase here, because it pulls in dlopen which we
+  // can't have when being compiled statically.
+  std::unique_ptr<android::base::MappedFile> map =
+      android::base::MappedFile::FromFd(fd, offset, length, PROT_READ);
+  if (map == nullptr) {
+    *ext_error_msg = new ExtDexFileString{
+        android::base::StringPrintf("mmap '%s' failed: %s", location, std::strerror(errno))};
+    return false;
+  }
+
+  const art::DexFile::Header* header = reinterpret_cast<const art::DexFile::Header*>(map->data());
+  uint32_t file_size;
+  if (__builtin_add_overflow(offset, header->file_size_, &file_size)) {
+    *ext_error_msg =
+        new ExtDexFileString{android::base::StringPrintf("Corrupt header in '%s'", location)};
+    return false;
+  }
+  if (length < file_size) {
+    *ext_error_msg = new ExtDexFileString{
+        android::base::StringPrintf("Dex file '%s' too short: expected %" PRIu32 ", got %" PRIu64,
+                                    location,
+                                    file_size,
+                                    uint64_t{length})};
+    return false;
+  }
+
+  void* addr = map->data();
+  size_t size = map->size();
+  auto container = std::make_unique<art::MappedFileContainer>(std::move(map));
+
+  std::string loc_str(location);
+  std::string error_msg;
+  art::DexFileLoader loader;
+  std::unique_ptr<const art::DexFile> dex_file = loader.Open(reinterpret_cast<const uint8_t*>(addr),
+                                                             size,
+                                                             loc_str,
+                                                             header->checksum_,
+                                                             /*oat_dex_file=*/nullptr,
+                                                             /*verify=*/false,
+                                                             /*verify_checksum=*/false,
+                                                             &error_msg,
+                                                             std::move(container));
+  if (dex_file == nullptr) {
+    *ext_error_msg = new ExtDexFileString{std::move(error_msg)};
+    return false;
+  }
+  *ext_dex_file = new ExtDexFile(std::move(dex_file));
+  return true;
+}
+
+int ExtDexFileGetMethodInfoForOffset(ExtDexFile* ext_dex_file,
+                                     int64_t dex_offset,
+                                     /*out*/ ExtDexFileMethodInfo* method_info) {
+  if (!ext_dex_file->dex_file_->IsInDataSection(ext_dex_file->dex_file_->Begin() + dex_offset)) {
+    return false;  // The DEX offset is not within the bytecode of this dex file.
+  }
+
+  if (ext_dex_file->dex_file_->IsCompactDexFile()) {
+    // The data section of compact dex files might be shared.
+    // Check the subrange unique to this compact dex.
+    const art::CompactDexFile::Header& cdex_header =
+        ext_dex_file->dex_file_->AsCompactDexFile()->GetHeader();
+    uint32_t begin = cdex_header.data_off_ + cdex_header.OwnedDataBegin();
+    uint32_t end = cdex_header.data_off_ + cdex_header.OwnedDataEnd();
+    if (dex_offset < begin || dex_offset >= end) {
+      return false;  // The DEX offset is not within the bytecode of this dex file.
+    }
+  }
+
+  art::MethodCacheEntry* entry = ext_dex_file->GetMethodCacheEntryForOffset(dex_offset);
+  if (entry != nullptr) {
+    method_info->offset = entry->offset;
+    method_info->len = entry->len;
+    method_info->name = new ExtDexFileString{ext_dex_file->GetMethodName(*entry)};
+    return true;
+  }
+
+  return false;
+}
+
+void ExtDexFileGetAllMethodInfos(ExtDexFile* ext_dex_file,
+                                 int with_signature,
+                                 ExtDexFileMethodInfoCallback* method_info_cb,
+                                 void* user_data) {
+  for (art::ClassAccessor accessor : ext_dex_file->dex_file_->GetClasses()) {
+    for (const art::ClassAccessor::Method& method : accessor.GetMethods()) {
+      art::CodeItemInstructionAccessor code = method.GetInstructions();
+      if (!code.HasCodeItem()) {
+        continue;
+      }
+
+      ExtDexFileMethodInfo method_info;
+      method_info.offset = static_cast<int32_t>(reinterpret_cast<const uint8_t*>(code.Insns()) -
+                                                ext_dex_file->dex_file_->Begin());
+      method_info.len = code.InsnsSizeInBytes();
+      method_info.name = new ExtDexFileString{
+          ext_dex_file->dex_file_->PrettyMethod(method.GetIndex(), with_signature)};
+      method_info_cb(&method_info, user_data);
+    }
+  }
+}
+
+void ExtDexFileFree(ExtDexFile* ext_dex_file) { delete (ext_dex_file); }
+
+}  // extern "C"
