Merge "Copying debug ramdisk files to /debug_ramdisk/*"
diff --git a/adb/adb.cpp b/adb/adb.cpp
index e417f05..2dd22b3 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -280,6 +280,9 @@
     } else if (type == "sideload") {
         D("setting connection_state to kCsSideload");
         t->SetConnectionState(kCsSideload);
+    } else if (type == "rescue") {
+        D("setting connection_state to kCsRescue");
+        t->SetConnectionState(kCsRescue);
     } else {
         D("setting connection_state to kCsHost");
         t->SetConnectionState(kCsHost);
diff --git a/adb/adb.h b/adb/adb.h
index c60dcbc..3a6f059 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -107,6 +107,7 @@
     kCsHost,
     kCsRecovery,
     kCsSideload,
+    kCsRescue,
 };
 
 inline bool ConnectionStateIsOnline(ConnectionState state) {
@@ -116,6 +117,7 @@
         case kCsHost:
         case kCsRecovery:
         case kCsSideload:
+        case kCsRescue:
             return true;
         default:
             return false;
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 43a3e5e..f25955d 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -190,7 +190,7 @@
         "scripting:\n"
         " wait-for[-TRANSPORT]-STATE\n"
         "     wait for device to be in the given state\n"
-        "     STATE: device, recovery, sideload, bootloader, or disconnect\n"
+        "     STATE: device, recovery, rescue, sideload, bootloader, or disconnect\n"
         "     TRANSPORT: usb, local, or any [default=any]\n"
         " get-state                print offline | bootloader | device\n"
         " get-serialno             print <serial-number>\n"
@@ -1037,11 +1037,12 @@
     }
 
     if (components[3] != "any" && components[3] != "bootloader" && components[3] != "device" &&
-        components[3] != "recovery" && components[3] != "sideload" &&
+        components[3] != "recovery" && components[3] != "rescue" && components[3] != "sideload" &&
         components[3] != "disconnect") {
         fprintf(stderr,
                 "adb: unknown state %s; "
-                "expected 'any', 'bootloader', 'device', 'recovery', 'sideload', or 'disconnect'\n",
+                "expected 'any', 'bootloader', 'device', 'recovery', 'rescue', 'sideload', or "
+                "'disconnect'\n",
                 components[3].c_str());
         return false;
     }
diff --git a/adb/services.cpp b/adb/services.cpp
index cf346ba..335ffc4 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -227,6 +227,8 @@
             sinfo->state = kCsDevice;
         } else if (name == "-recovery") {
             sinfo->state = kCsRecovery;
+        } else if (name == "-rescue") {
+            sinfo->state = kCsRescue;
         } else if (name == "-sideload") {
             sinfo->state = kCsSideload;
         } else if (name == "-bootloader") {
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 15c3a9a..841865a 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -1012,6 +1012,8 @@
             return "host";
         case kCsRecovery:
             return "recovery";
+        case kCsRescue:
+            return "rescue";
         case kCsNoPerm:
             return UsbNoPermissionsShortHelpText();
         case kCsSideload:
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 0cf3378..2e226da 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -183,6 +183,12 @@
             ],
         },
     },
+
+    product_variables: {
+        debuggable: {
+            cflags: ["-DROOT_POSSIBLE"],
+        },
+    },
 }
 
 cc_test {
diff --git a/debuggerd/libdebuggerd/backtrace.cpp b/debuggerd/libdebuggerd/backtrace.cpp
index 94fcfb2..c606970 100644
--- a/debuggerd/libdebuggerd/backtrace.cpp
+++ b/debuggerd/libdebuggerd/backtrace.cpp
@@ -74,10 +74,7 @@
     return;
   }
 
-  unwinder->SetDisplayBuildID(true);
-  for (size_t i = 0; i < unwinder->NumFrames(); i++) {
-    _LOG(&log, logtype::BACKTRACE, "  %s\n", unwinder->FormatFrame(i).c_str());
-  }
+  log_backtrace(&log, unwinder, "  ");
 }
 
 void dump_backtrace(android::base::unique_fd output_fd, unwindstack::Unwinder* unwinder,
diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
index 238c00c..f189c45 100644
--- a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
+++ b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
@@ -73,9 +73,12 @@
 void _LOG(log_t* log, logtype ltype, const char* fmt, ...) __attribute__((format(printf, 3, 4)));
 
 namespace unwindstack {
+class Unwinder;
 class Memory;
 }
 
+void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix);
+
 void dump_memory(log_t* log, unwindstack::Memory* backtrace, uint64_t addr, const std::string&);
 
 void read_with_default(const char* path, char* buf, size_t len, const char* default_value);
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index cc337ed..d1726cd 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -371,13 +371,6 @@
   }
 }
 
-void dump_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix) {
-  unwinder->SetDisplayBuildID(true);
-  for (size_t i = 0; i < unwinder->NumFrames(); i++) {
-    _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, unwinder->FormatFrame(i).c_str());
-  }
-}
-
 static void print_register_row(log_t* log,
                                const std::vector<std::pair<std::string, uint64_t>>& registers) {
   std::string output;
@@ -470,7 +463,7 @@
     _LOG(log, logtype::THREAD, "Failed to unwind");
   } else {
     _LOG(log, logtype::BACKTRACE, "\nbacktrace:\n");
-    dump_backtrace(log, unwinder, "    ");
+    log_backtrace(log, unwinder, "    ");
 
     _LOG(log, logtype::STACK, "\nstack:\n");
     dump_stack(log, unwinder->frames(), unwinder->GetMaps(), unwinder->GetProcessMemory().get());
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp
index 7aebea8..9b2779a 100644
--- a/debuggerd/libdebuggerd/utility.cpp
+++ b/debuggerd/libdebuggerd/utility.cpp
@@ -38,6 +38,7 @@
 #include <debuggerd/handler.h>
 #include <log/log.h>
 #include <unwindstack/Memory.h>
+#include <unwindstack/Unwinder.h>
 
 using android::base::unique_fd;
 
@@ -422,3 +423,22 @@
   // Then give up...
   return "?";
 }
+
+void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix) {
+  if (unwinder->elf_from_memory_not_file()) {
+    _LOG(log, logtype::BACKTRACE,
+         "%sNOTE: Function names and BuildId information is missing for some frames due\n", prefix);
+    _LOG(log, logtype::BACKTRACE,
+         "%sNOTE: to unreadable libraries. For unwinds of apps, only shared libraries\n", prefix);
+    _LOG(log, logtype::BACKTRACE, "%sNOTE: found under the lib/ directory are readable.\n", prefix);
+#if defined(ROOT_POSSIBLE)
+    _LOG(log, logtype::BACKTRACE,
+         "%sNOTE: On this device, run setenforce 0 to make the libraries readable.\n", prefix);
+#endif
+  }
+
+  unwinder->SetDisplayBuildID(true);
+  for (size_t i = 0; i < unwinder->NumFrames(); i++) {
+    _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, unwinder->FormatFrame(i).c_str());
+  }
+}
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 5114f55..c1aafda 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1695,11 +1695,12 @@
 
 std::string fs_mgr_get_super_partition_name(int slot) {
     // Devices upgrading to dynamic partitions are allowed to specify a super
-    // partition name, assumed to be A/B (non-A/B retrofit is not supported).
-    // For devices launching with dynamic partition support, the partition
-    // name must be "super".
+    // partition name. This includes cuttlefish, which is a non-A/B device.
     std::string super_partition;
     if (fs_mgr_get_boot_config_from_kernel_cmdline("super_partition", &super_partition)) {
+        if (fs_mgr_get_slot_suffix().empty()) {
+            return super_partition;
+        }
         std::string suffix;
         if (slot == 0) {
             suffix = "_a";
diff --git a/init/init.cpp b/init/init.cpp
index 82415f9..c79e459 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -636,6 +636,11 @@
     InitKernelLogging(argv, InitAborter);
     LOG(INFO) << "init second stage started!";
 
+    // Set init and its forked children's oom_adj.
+    if (auto result = WriteFile("/proc/1/oom_score_adj", "-1000"); !result) {
+        LOG(ERROR) << "Unable to write -1000 to /proc/1/oom_score_adj: " << result.error();
+    }
+
     // Enable seccomp if global boot option was passed (otherwise it is enabled in zygote).
     GlobalSeccomp();
 
diff --git a/init/property_service.h b/init/property_service.h
index 85e7bc0..207c03b 100644
--- a/init/property_service.h
+++ b/init/property_service.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef _INIT_PROPERTY_H
-#define _INIT_PROPERTY_H
+#pragma once
 
 #include <sys/socket.h>
 
@@ -35,13 +34,10 @@
 
 extern bool PropertyChildReap(pid_t pid);
 
-void property_init(void);
-void property_load_boot_defaults(bool);
-void load_persist_props(void);
-void load_system_props(void);
+void property_init();
+void property_load_boot_defaults(bool load_debug_prop);
+void load_persist_props();
 void StartPropertyService(Epoll* epoll);
 
 }  // namespace init
 }  // namespace android
-
-#endif  /* _INIT_PROPERTY_H */
diff --git a/libunwindstack/MapInfo.cpp b/libunwindstack/MapInfo.cpp
index 28373b2..03658b4 100644
--- a/libunwindstack/MapInfo.cpp
+++ b/libunwindstack/MapInfo.cpp
@@ -161,6 +161,7 @@
   // option is used.
   std::unique_ptr<MemoryRange> memory(new MemoryRange(process_memory, start, end - start, 0));
   if (Elf::IsValidElf(memory.get())) {
+    memory_backed_elf = true;
     return memory.release();
   }
 
@@ -184,6 +185,7 @@
       new MemoryRange(process_memory, prev_map->start, prev_map->end - prev_map->start, 0));
   ranges->Insert(new MemoryRange(process_memory, start, end - start, elf_offset));
 
+  memory_backed_elf = true;
   return ranges;
 }
 
@@ -237,6 +239,7 @@
     std::lock_guard<std::mutex> guard(prev_map->mutex_);
     if (prev_map->elf.get() == nullptr) {
       prev_map->elf = elf;
+      prev_map->memory_backed_elf = memory_backed_elf;
     }
   }
   return elf.get();
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp
index f3d2b5e..26626b5 100644
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -141,6 +141,7 @@
   frames_.clear();
   last_error_.code = ERROR_NONE;
   last_error_.address = 0;
+  elf_from_memory_not_file_ = false;
 
   ArchEnum arch = regs_->Arch();
 
@@ -164,6 +165,12 @@
         break;
       }
       elf = map_info->GetElf(process_memory_, arch);
+      // If this elf is memory backed, and there is a valid file, then set
+      // an indicator that we couldn't open the file.
+      if (!elf_from_memory_not_file_ && map_info->memory_backed_elf && !map_info->name.empty() &&
+          map_info->name[0] != '[') {
+        elf_from_memory_not_file_ = true;
+      }
       step_pc = regs_->pc();
       rel_pc = elf->GetRelPc(step_pc, map_info);
       // Everyone except elf data in gdb jit debug maps uses the relative pc.
diff --git a/libunwindstack/include/unwindstack/MapInfo.h b/libunwindstack/include/unwindstack/MapInfo.h
index e938986..025fd98 100644
--- a/libunwindstack/include/unwindstack/MapInfo.h
+++ b/libunwindstack/include/unwindstack/MapInfo.h
@@ -75,6 +75,9 @@
   // make it easier to move to a fine grained lock in the future.
   std::atomic_uintptr_t build_id;
 
+  // Set to true if the elf file data is coming from memory.
+  bool memory_backed_elf = false;
+
   // This function guarantees it will never return nullptr.
   Elf* GetElf(const std::shared_ptr<Memory>& process_memory, ArchEnum expected_arch);
 
diff --git a/libunwindstack/include/unwindstack/Unwinder.h b/libunwindstack/include/unwindstack/Unwinder.h
index 75be209..52b3578 100644
--- a/libunwindstack/include/unwindstack/Unwinder.h
+++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -111,6 +111,8 @@
   void SetDexFiles(DexFiles* dex_files, ArchEnum arch);
 #endif
 
+  bool elf_from_memory_not_file() { return elf_from_memory_not_file_; }
+
   ErrorCode LastErrorCode() { return last_error_.code; }
   uint64_t LastErrorAddress() { return last_error_.address; }
 
@@ -132,6 +134,9 @@
   bool resolve_names_ = true;
   bool embedded_soname_ = true;
   bool display_build_id_ = false;
+  // True if at least one elf file is coming from memory and not the related
+  // file. This is only true if there is an actual file backing up the elf.
+  bool elf_from_memory_not_file_ = false;
   ErrorData last_error_;
 };
 
diff --git a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
index 2ddadef..6be8bdc 100644
--- a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
+++ b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
@@ -108,6 +108,7 @@
   info.end = 0x101;
   memory.reset(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
+  EXPECT_FALSE(info.memory_backed_elf);
 }
 
 // Verify that if the offset is non-zero but there is no elf at the offset,
@@ -117,6 +118,7 @@
 
   std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
+  EXPECT_FALSE(info.memory_backed_elf);
   ASSERT_EQ(0x100U, info.elf_offset);
   EXPECT_EQ(0x100U, info.elf_start_offset);
 
@@ -140,32 +142,40 @@
   // offset to zero.
   info.elf_offset = 0;
   info.elf_start_offset = 0;
+  info.memory_backed_elf = false;
   memory.reset(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
+  EXPECT_FALSE(info.memory_backed_elf);
   ASSERT_EQ(0x100U, info.elf_offset);
   EXPECT_EQ(0x100U, info.elf_start_offset);
 
   prev_info.offset = 0;
   info.elf_offset = 0;
   info.elf_start_offset = 0;
+  info.memory_backed_elf = false;
   memory.reset(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
+  EXPECT_FALSE(info.memory_backed_elf);
   ASSERT_EQ(0x100U, info.elf_offset);
   EXPECT_EQ(0x100U, info.elf_start_offset);
 
   prev_info.flags = PROT_READ;
   info.elf_offset = 0;
   info.elf_start_offset = 0;
+  info.memory_backed_elf = false;
   memory.reset(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
+  EXPECT_FALSE(info.memory_backed_elf);
   ASSERT_EQ(0x100U, info.elf_offset);
   EXPECT_EQ(0x100U, info.elf_start_offset);
 
   prev_info.name = info.name;
   info.elf_offset = 0;
   info.elf_start_offset = 0;
+  info.memory_backed_elf = false;
   memory.reset(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
+  EXPECT_FALSE(info.memory_backed_elf);
   ASSERT_EQ(0x100U, info.elf_offset);
   EXPECT_EQ(0U, info.elf_start_offset);
 }
@@ -177,6 +187,7 @@
 
   std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
+  EXPECT_FALSE(info.memory_backed_elf);
   ASSERT_EQ(0U, info.elf_offset);
   EXPECT_EQ(0x1000U, info.elf_start_offset);
 
@@ -201,6 +212,7 @@
 
   std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
+  EXPECT_FALSE(info.memory_backed_elf);
   ASSERT_EQ(0U, info.elf_offset);
   EXPECT_EQ(0x1000U, info.elf_start_offset);
 
@@ -218,6 +230,7 @@
 
   std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
+  EXPECT_FALSE(info.memory_backed_elf);
   ASSERT_EQ(0U, info.elf_offset);
   EXPECT_EQ(0x2000U, info.elf_start_offset);
 
@@ -259,6 +272,7 @@
 
   std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
+  EXPECT_TRUE(info.memory_backed_elf);
 
   memset(buffer.data(), 0, buffer.size());
   ASSERT_TRUE(memory->ReadFully(0, buffer.data(), buffer.size()));
@@ -290,6 +304,7 @@
 
   std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
   ASSERT_TRUE(mem.get() != nullptr);
+  EXPECT_TRUE(map_info->memory_backed_elf);
   EXPECT_EQ(0x4000UL, map_info->elf_offset);
   EXPECT_EQ(0x4000UL, map_info->offset);
   EXPECT_EQ(0U, map_info->elf_start_offset);
@@ -336,6 +351,7 @@
 
   std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
   ASSERT_TRUE(mem.get() != nullptr);
+  EXPECT_TRUE(map_info->memory_backed_elf);
   EXPECT_EQ(0x1000UL, map_info->elf_offset);
   EXPECT_EQ(0xb000UL, map_info->offset);
   EXPECT_EQ(0xa000UL, map_info->elf_start_offset);
@@ -374,6 +390,7 @@
   // extend over the executable segment.
   std::unique_ptr<Memory> memory(map_info->CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
+  EXPECT_FALSE(map_info->memory_backed_elf);
   std::vector<uint8_t> buffer(0x100);
   EXPECT_EQ(0x2000U, map_info->offset);
   EXPECT_EQ(0U, map_info->elf_offset);
@@ -388,7 +405,9 @@
   ASSERT_EQ(0x1000, lseek(elf_at_1000_.fd, 0x1000, SEEK_SET));
   ASSERT_TRUE(android::base::WriteFully(elf_at_1000_.fd, &ehdr, sizeof(ehdr)));
 
+  map_info->memory_backed_elf = false;
   memory.reset(map_info->CreateMemory(process_memory_));
+  EXPECT_FALSE(map_info->memory_backed_elf);
   EXPECT_EQ(0x2000U, map_info->offset);
   EXPECT_EQ(0x1000U, map_info->elf_offset);
   EXPECT_EQ(0x1000U, map_info->elf_start_offset);
diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp
index 48e038e..f635021 100644
--- a/libunwindstack/tests/UnwinderTest.cpp
+++ b/libunwindstack/tests/UnwinderTest.cpp
@@ -108,6 +108,24 @@
     const auto& info2 = *--maps_->end();
     info2->elf_offset = 0x8000;
 
+    elf = new ElfFake(new MemoryFake);
+    elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
+    AddMapInfo(0xc0000, 0xc1000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/unreadable.so", elf);
+    const auto& info3 = *--maps_->end();
+    info3->memory_backed_elf = true;
+
+    elf = new ElfFake(new MemoryFake);
+    elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
+    AddMapInfo(0xc1000, 0xc2000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "[vdso]", elf);
+    const auto& info4 = *--maps_->end();
+    info4->memory_backed_elf = true;
+
+    elf = new ElfFake(new MemoryFake);
+    elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
+    AddMapInfo(0xc2000, 0xc3000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "", elf);
+    const auto& info5 = *--maps_->end();
+    info5->memory_backed_elf = true;
+
     process_memory_.reset(new MemoryFake);
   }
 
@@ -140,6 +158,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(3U, unwinder.NumFrames());
 
@@ -204,6 +223,7 @@
   unwinder.SetResolveNames(false);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(3U, unwinder.NumFrames());
 
@@ -263,6 +283,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
 
@@ -292,6 +313,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
 
@@ -321,6 +343,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
 
@@ -351,6 +374,7 @@
   unwinder.SetEmbeddedSoname(false);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
 
@@ -387,6 +411,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
 
@@ -419,6 +444,7 @@
   Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(20U, unwinder.NumFrames());
 
@@ -461,6 +487,7 @@
   std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
   unwinder.Unwind(&skip_libs);
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(3U, unwinder.NumFrames());
 
@@ -522,6 +549,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
 
@@ -569,6 +597,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
 }
@@ -588,6 +617,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
 }
@@ -602,6 +632,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
 
@@ -638,6 +669,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(3U, unwinder.NumFrames());
 
@@ -703,6 +735,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
 
@@ -752,6 +785,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
 
@@ -799,6 +833,7 @@
   std::vector<std::string> skip_names{"libanother.so"};
   unwinder.Unwind(&skip_names);
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(0U, unwinder.NumFrames());
 }
@@ -821,6 +856,7 @@
   std::vector<std::string> suffixes{"oat"};
   unwinder.Unwind(nullptr, &suffixes);
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
   // Make sure the elf was not initialized.
@@ -879,6 +915,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(3U, unwinder.NumFrames());
 
@@ -937,6 +974,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
 
@@ -980,6 +1018,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
 
@@ -1026,6 +1065,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(3U, unwinder.NumFrames());
 
@@ -1084,6 +1124,7 @@
   Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
 
@@ -1103,6 +1144,96 @@
   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
 }
 
+TEST_F(UnwinderTest, elf_from_memory_not_file) {
+  ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
+
+  regs_.set_pc(0xc0050);
+  regs_.set_sp(0x10000);
+  ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
+
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
+  unwinder.Unwind();
+  EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_TRUE(unwinder.elf_from_memory_not_file());
+
+  ASSERT_EQ(1U, unwinder.NumFrames());
+
+  auto* frame = &unwinder.frames()[0];
+  EXPECT_EQ(0U, frame->num);
+  EXPECT_EQ(0x50U, frame->rel_pc);
+  EXPECT_EQ(0xc0050U, frame->pc);
+  EXPECT_EQ(0x10000U, frame->sp);
+  EXPECT_EQ("Frame0", frame->function_name);
+  EXPECT_EQ(0U, frame->function_offset);
+  EXPECT_EQ("/fake/unreadable.so", frame->map_name);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
+  EXPECT_EQ(0xc0000U, frame->map_start);
+  EXPECT_EQ(0xc1000U, frame->map_end);
+  EXPECT_EQ(0U, frame->map_load_bias);
+  EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
+}
+
+TEST_F(UnwinderTest, elf_from_memory_but_no_valid_file_with_bracket) {
+  ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
+
+  regs_.set_pc(0xc1050);
+  regs_.set_sp(0x10000);
+  ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
+
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
+  unwinder.Unwind();
+  EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
+
+  ASSERT_EQ(1U, unwinder.NumFrames());
+
+  auto* frame = &unwinder.frames()[0];
+  EXPECT_EQ(0U, frame->num);
+  EXPECT_EQ(0x50U, frame->rel_pc);
+  EXPECT_EQ(0xc1050U, frame->pc);
+  EXPECT_EQ(0x10000U, frame->sp);
+  EXPECT_EQ("Frame0", frame->function_name);
+  EXPECT_EQ(0U, frame->function_offset);
+  EXPECT_EQ("[vdso]", frame->map_name);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
+  EXPECT_EQ(0xc1000U, frame->map_start);
+  EXPECT_EQ(0xc2000U, frame->map_end);
+  EXPECT_EQ(0U, frame->map_load_bias);
+  EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
+}
+
+TEST_F(UnwinderTest, elf_from_memory_but_empty_filename) {
+  ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
+
+  regs_.set_pc(0xc2050);
+  regs_.set_sp(0x10000);
+  ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
+
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
+  unwinder.Unwind();
+  EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_FALSE(unwinder.elf_from_memory_not_file());
+
+  ASSERT_EQ(1U, unwinder.NumFrames());
+
+  auto* frame = &unwinder.frames()[0];
+  EXPECT_EQ(0U, frame->num);
+  EXPECT_EQ(0x50U, frame->rel_pc);
+  EXPECT_EQ(0xc2050U, frame->pc);
+  EXPECT_EQ(0x10000U, frame->sp);
+  EXPECT_EQ("Frame0", frame->function_name);
+  EXPECT_EQ(0U, frame->function_offset);
+  EXPECT_EQ("", frame->map_name);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
+  EXPECT_EQ(0xc2000U, frame->map_start);
+  EXPECT_EQ(0xc3000U, frame->map_end);
+  EXPECT_EQ(0U, frame->map_load_bias);
+  EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
+}
+
 // Verify format frame code.
 TEST_F(UnwinderTest, format_frame) {
   RegsFake regs_arm(10);
diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp
index bc1543b..858c0bb 100644
--- a/libziparchive/Android.bp
+++ b/libziparchive/Android.bp
@@ -26,6 +26,8 @@
         // Incorrectly warns when C++11 empty brace {} initializer is used.
         // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61489
         "-Wno-missing-field-initializers",
+        "-Wconversion",
+        "-Wno-sign-conversion",
     ],
 
     // Enable -Wold-style-cast only for non-Windows targets.  _islower_l,
diff --git a/libziparchive/entry_name_utils-inl.h b/libziparchive/entry_name_utils-inl.h
index 1714586..10311b5 100644
--- a/libziparchive/entry_name_utils-inl.h
+++ b/libziparchive/entry_name_utils-inl.h
@@ -20,9 +20,15 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <limits>
+
 // Check if |length| bytes at |entry_name| constitute a valid entry name.
-// Entry names must be valid UTF-8 and must not contain '0'.
+// Entry names must be valid UTF-8 and must not contain '0'. They also must
+// fit into the central directory record.
 inline bool IsValidEntryName(const uint8_t* entry_name, const size_t length) {
+  if (length > std::numeric_limits<uint16_t>::max()) {
+    return false;
+  }
   for (size_t i = 0; i < length; ++i) {
     const uint8_t byte = entry_name[i];
     if (byte == 0) {
@@ -35,7 +41,8 @@
       return false;
     } else {
       // 2-5 byte sequences.
-      for (uint8_t first = (byte & 0x7f) << 1; first & 0x80; first = (first & 0x7f) << 1) {
+      for (uint8_t first = static_cast<uint8_t>((byte & 0x7f) << 1); first & 0x80;
+           first = static_cast<uint8_t>((first & 0x7f) << 1)) {
         ++i;
 
         // Missing continuation byte..
diff --git a/libziparchive/include/ziparchive/zip_writer.h b/libziparchive/include/ziparchive/zip_writer.h
index f6c8427..bd44fdb 100644
--- a/libziparchive/include/ziparchive/zip_writer.h
+++ b/libziparchive/include/ziparchive/zip_writer.h
@@ -76,7 +76,7 @@
     uint32_t uncompressed_size;
     uint16_t last_mod_time;
     uint16_t last_mod_date;
-    uint32_t padding_length;
+    uint16_t padding_length;
     off64_t local_file_header_offset;
   };
 
@@ -161,8 +161,8 @@
 
   int32_t HandleError(int32_t error_code);
   int32_t PrepareDeflate();
-  int32_t StoreBytes(FileEntry* file, const void* data, size_t len);
-  int32_t CompressBytes(FileEntry* file, const void* data, size_t len);
+  int32_t StoreBytes(FileEntry* file, const void* data, uint32_t len);
+  int32_t CompressBytes(FileEntry* file, const void* data, uint32_t len);
   int32_t FlushCompressedBytes(FileEntry* file);
 
   enum class State {
diff --git a/libziparchive/unzip.cpp b/libziparchive/unzip.cpp
index cc059d8..c6def73 100644
--- a/libziparchive/unzip.cpp
+++ b/libziparchive/unzip.cpp
@@ -85,7 +85,7 @@
 
 static int CompressionRatio(int64_t uncompressed, int64_t compressed) {
   if (uncompressed == 0) return 0;
-  return (100LL * (uncompressed - compressed)) / uncompressed;
+  return static_cast<int>((100LL * (uncompressed - compressed)) / uncompressed);
 }
 
 static void MaybeShowHeader() {
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index e1ec47a..596786a 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -146,7 +146,7 @@
 /*
  * Add a new entry to the hash table.
  */
-static int32_t AddToHash(ZipStringOffset* hash_table, const uint64_t hash_table_size,
+static int32_t AddToHash(ZipStringOffset* hash_table, const uint32_t hash_table_size,
                          const ZipString& name, const uint8_t* start) {
   const uint64_t hash = ComputeHash(name);
   uint32_t ent = hash & (hash_table_size - 1);
@@ -214,7 +214,7 @@
 }
 
 static int32_t MapCentralDirectory0(const char* debug_file_name, ZipArchive* archive,
-                                    off64_t file_length, off64_t read_amount,
+                                    off64_t file_length, uint32_t read_amount,
                                     uint8_t* scan_buffer) {
   const off64_t search_start = file_length - read_amount;
 
@@ -230,7 +230,8 @@
    * doing an initial minimal read; if we don't find it, retry with a
    * second read as above.)
    */
-  int i = read_amount - sizeof(EocdRecord);
+  CHECK_LE(read_amount, std::numeric_limits<int32_t>::max());
+  int32_t i = read_amount - sizeof(EocdRecord);
   for (; i >= 0; i--) {
     if (scan_buffer[i] == 0x50) {
       uint32_t* sig_addr = reinterpret_cast<uint32_t*>(&scan_buffer[i]);
@@ -333,9 +334,9 @@
    *
    * We start by pulling in the last part of the file.
    */
-  off64_t read_amount = kMaxEOCDSearch;
+  uint32_t read_amount = kMaxEOCDSearch;
   if (file_length < read_amount) {
-    read_amount = file_length;
+    read_amount = static_cast<uint32_t>(file_length);
   }
 
   std::vector<uint8_t> scan_buffer(read_amount);
@@ -532,7 +533,7 @@
   return 0;
 }
 
-static int32_t FindEntry(const ZipArchive* archive, const int ent, ZipEntry* data) {
+static int32_t FindEntry(const ZipArchive* archive, const int32_t ent, ZipEntry* data) {
   const uint16_t nameLen = archive->hash_table[ent].name_length;
 
   // Recover the start of the central directory entry from the filename
@@ -751,9 +752,10 @@
                                    archive->central_directory.GetBasePtr());
   if (ent < 0) {
     ALOGV("Zip: Could not find entry %.*s", entryName.name_length, entryName.name);
-    return ent;
+    return static_cast<int32_t>(ent);  // kEntryNotFound is safe to truncate.
   }
-  return FindEntry(archive, ent, data);
+  // We know there are at most hast_table_size entries, safe to truncate.
+  return FindEntry(archive, static_cast<uint32_t>(ent), data);
 }
 
 int32_t Next(void* cookie, ZipEntry* data, ZipString* name) {
@@ -836,7 +838,6 @@
       return FileWriter{};
     }
 
-    int result = 0;
 #if defined(__linux__)
     if (declared_length > 0) {
       // Make sure we have enough space on the volume to extract the compressed
@@ -848,7 +849,7 @@
       // EOPNOTSUPP error when issued in other filesystems.
       // Hence, check for the return error code before concluding that the
       // disk does not have enough space.
-      result = TEMP_FAILURE_RETRY(fallocate(fd, 0, current_offset, declared_length));
+      long result = TEMP_FAILURE_RETRY(fallocate(fd, 0, current_offset, declared_length));
       if (result == -1 && errno == ENOSPC) {
         ALOGW("Zip: unable to allocate %" PRId64 " bytes at offset %" PRId64 ": %s",
               static_cast<int64_t>(declared_length), static_cast<int64_t>(current_offset),
@@ -866,7 +867,7 @@
 
     // Block device doesn't support ftruncate(2).
     if (!S_ISBLK(sb.st_mode)) {
-      result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
+      long result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
       if (result == -1) {
         ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
               static_cast<int64_t>(declared_length + current_offset), strerror(errno));
@@ -985,16 +986,16 @@
   std::unique_ptr<z_stream, decltype(zstream_deleter)> zstream_guard(&zstream, zstream_deleter);
 
   const bool compute_crc = (crc_out != nullptr);
-  uint64_t crc = 0;
+  uLong crc = 0;
   uint32_t remaining_bytes = compressed_length;
   do {
     /* read as much as we can */
     if (zstream.avail_in == 0) {
-      const size_t read_size = (remaining_bytes > kBufSize) ? kBufSize : remaining_bytes;
+      const uint32_t read_size = (remaining_bytes > kBufSize) ? kBufSize : remaining_bytes;
       const uint32_t offset = (compressed_length - remaining_bytes);
       // Make sure to read at offset to ensure concurrent access to the fd.
       if (!reader.ReadAtOffset(read_buf.data(), read_size, offset)) {
-        ALOGW("Zip: inflate read failed, getSize = %zu: %s", read_size, strerror(errno));
+        ALOGW("Zip: inflate read failed, getSize = %u: %s", read_size, strerror(errno));
         return kIoError;
       }
 
@@ -1018,7 +1019,8 @@
       if (!writer->Append(&write_buf[0], write_size)) {
         return kIoError;
       } else if (compute_crc) {
-        crc = crc32(crc, &write_buf[0], write_size);
+        DCHECK_LE(write_size, kBufSize);
+        crc = crc32(crc, &write_buf[0], static_cast<uint32_t>(write_size));
       }
 
       zstream.next_out = &write_buf[0];
@@ -1063,17 +1065,17 @@
 
   const uint32_t length = entry->uncompressed_length;
   uint32_t count = 0;
-  uint64_t crc = 0;
+  uLong crc = 0;
   while (count < length) {
     uint32_t remaining = length - count;
     off64_t offset = entry->offset + count;
 
     // Safe conversion because kBufSize is narrow enough for a 32 bit signed value.
-    const size_t block_size = (remaining > kBufSize) ? kBufSize : remaining;
+    const uint32_t block_size = (remaining > kBufSize) ? kBufSize : remaining;
 
     // Make sure to read at offset to ensure concurrent access to the fd.
     if (!mapped_zip.ReadAtOffset(buf.data(), block_size, offset)) {
-      ALOGW("CopyFileToFile: copy read failed, block_size = %zu, offset = %" PRId64 ": %s",
+      ALOGW("CopyFileToFile: copy read failed, block_size = %u, offset = %" PRId64 ": %s",
             block_size, static_cast<int64_t>(offset), strerror(errno));
       return kIoError;
     }
diff --git a/libziparchive/zip_archive_stream_entry.cc b/libziparchive/zip_archive_stream_entry.cc
index 9ec89b1..1ec95b6 100644
--- a/libziparchive/zip_archive_stream_entry.cc
+++ b/libziparchive/zip_archive_stream_entry.cc
@@ -27,6 +27,7 @@
 #include <vector>
 
 #include <android-base/file.h>
+#include <android-base/logging.h>
 #include <log/log.h>
 
 #include <ziparchive/zip_archive.h>
@@ -77,6 +78,12 @@
 }
 
 const std::vector<uint8_t>* ZipArchiveStreamEntryUncompressed::Read() {
+  // Simple sanity check. The vector should *only* be handled by this code. A caller
+  // should not const-cast and modify the capacity. This may invalidate next_out.
+  //
+  // Note: it would be better to store the results of data() across Read calls.
+  CHECK_EQ(data_.capacity(), kBufSize);
+
   if (length_ == 0) {
     return nullptr;
   }
@@ -97,7 +104,8 @@
   if (bytes < data_.size()) {
     data_.resize(bytes);
   }
-  computed_crc32_ = crc32(computed_crc32_, data_.data(), data_.size());
+  computed_crc32_ = static_cast<uint32_t>(
+      crc32(computed_crc32_, data_.data(), static_cast<uint32_t>(data_.size())));
   length_ -= bytes;
   offset_ += bytes;
   return &data_;
@@ -192,9 +200,15 @@
 }
 
 const std::vector<uint8_t>* ZipArchiveStreamEntryCompressed::Read() {
+  // Simple sanity check. The vector should *only* be handled by this code. A caller
+  // should not const-cast and modify the capacity. This may invalidate next_out.
+  //
+  // Note: it would be better to store the results of data() across Read calls.
+  CHECK_EQ(out_.capacity(), kBufSize);
+
   if (z_stream_.avail_out == 0) {
     z_stream_.next_out = out_.data();
-    z_stream_.avail_out = out_.size();
+    z_stream_.avail_out = static_cast<uint32_t>(out_.size());
     ;
   }
 
@@ -203,7 +217,9 @@
       if (compressed_length_ == 0) {
         return nullptr;
       }
-      size_t bytes = (compressed_length_ > in_.size()) ? in_.size() : compressed_length_;
+      DCHECK_LE(in_.size(), std::numeric_limits<uint32_t>::max());  // Should be buf size = 64k.
+      uint32_t bytes = (compressed_length_ > in_.size()) ? static_cast<uint32_t>(in_.size())
+                                                         : compressed_length_;
       ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle_);
       errno = 0;
       if (!archive->mapped_zip.ReadAtOffset(in_.data(), bytes, offset_)) {
@@ -230,14 +246,16 @@
 
     if (z_stream_.avail_out == 0) {
       uncompressed_length_ -= out_.size();
-      computed_crc32_ = crc32(computed_crc32_, out_.data(), out_.size());
+      computed_crc32_ = static_cast<uint32_t>(
+          crc32(computed_crc32_, out_.data(), static_cast<uint32_t>(out_.size())));
       return &out_;
     }
     if (zerr == Z_STREAM_END) {
       if (z_stream_.avail_out != 0) {
         // Resize the vector down to the actual size of the data.
         out_.resize(out_.size() - z_stream_.avail_out);
-        computed_crc32_ = crc32(computed_crc32_, out_.data(), out_.size());
+        computed_crc32_ = static_cast<uint32_t>(
+            crc32(computed_crc32_, out_.data(), static_cast<uint32_t>(out_.size())));
         uncompressed_length_ -= out_.size();
         return &out_;
       }
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index cea42d4..e471d5e 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -27,6 +27,7 @@
 #include <vector>
 
 #include <android-base/file.h>
+#include <android-base/logging.h>
 #include <android-base/mapped_file.h>
 #include <android-base/unique_fd.h>
 #include <gtest/gtest.h>
@@ -65,7 +66,8 @@
 
 static void SetZipString(ZipString* zip_str, const std::string& str) {
   zip_str->name = reinterpret_cast<const uint8_t*>(str.c_str());
-  zip_str->name_length = str.size();
+  CHECK_LE(str.size(), std::numeric_limits<uint16_t>::max());
+  zip_str->name_length = static_cast<uint16_t>(str.size());
 }
 
 TEST(ziparchive, Open) {
@@ -332,7 +334,7 @@
 
   // Extract the entry to memory.
   std::vector<uint8_t> buffer(kAbUncompressedSize);
-  ASSERT_EQ(0, ExtractToMemory(handle, &entry, &buffer[0], buffer.size()));
+  ASSERT_EQ(0, ExtractToMemory(handle, &entry, &buffer[0], static_cast<uint32_t>(buffer.size())));
 
   // Extract the entry to a file.
   TemporaryFile tmp_output_file;
@@ -415,7 +417,8 @@
   ASSERT_EQ(0, fstat(fd, &sb));
 
   // Memory map the file first and open the archive from the memory region.
-  auto file_map{android::base::MappedFile::FromFd(fd, 0, sb.st_size, PROT_READ)};
+  auto file_map{
+      android::base::MappedFile::FromFd(fd, 0, static_cast<size_t>(sb.st_size), PROT_READ)};
   ZipArchiveHandle handle;
   ASSERT_EQ(0,
             OpenArchiveFromMemory(file_map->data(), file_map->size(), zip_path.c_str(), &handle));
@@ -488,7 +491,8 @@
 
   std::vector<uint8_t> cmp_data(entry.uncompressed_length);
   ASSERT_EQ(entry.uncompressed_length, read_data.size());
-  ASSERT_EQ(0, ExtractToMemory(handle, &entry, cmp_data.data(), cmp_data.size()));
+  ASSERT_EQ(
+      0, ExtractToMemory(handle, &entry, cmp_data.data(), static_cast<uint32_t>(cmp_data.size())));
   ASSERT_TRUE(memcmp(read_data.data(), cmp_data.data(), read_data.size()) == 0);
 
   CloseArchive(handle);
@@ -737,8 +741,8 @@
 };
 
 TEST(ziparchive, Inflate) {
-  const uint32_t compressed_length = kATxtContentsCompressed.size();
-  const uint32_t uncompressed_length = kATxtContents.size();
+  const uint32_t compressed_length = static_cast<uint32_t>(kATxtContentsCompressed.size());
+  const uint32_t uncompressed_length = static_cast<uint32_t>(kATxtContents.size());
 
   const VectorReader reader(kATxtContentsCompressed);
   {
diff --git a/libziparchive/zip_writer.cc b/libziparchive/zip_writer.cc
index 0df0fa5..ae9d145 100644
--- a/libziparchive/zip_writer.cc
+++ b/libziparchive/zip_writer.cc
@@ -169,8 +169,8 @@
     year = 80;
   }
 
-  *out_date = (year - 80) << 9 | (ptm->tm_mon + 1) << 5 | ptm->tm_mday;
-  *out_time = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
+  *out_date = static_cast<uint16_t>((year - 80) << 9 | (ptm->tm_mon + 1) << 5 | ptm->tm_mday);
+  *out_time = static_cast<uint16_t>(ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1);
 }
 
 static void CopyFromFileEntry(const ZipWriter::FileEntry& src, bool use_data_descriptor,
@@ -193,7 +193,8 @@
   dst->compression_method = src.compression_method;
   dst->last_mod_time = src.last_mod_time;
   dst->last_mod_date = src.last_mod_date;
-  dst->file_name_length = src.path.size();
+  DCHECK_LE(src.path.size(), std::numeric_limits<uint16_t>::max());
+  dst->file_name_length = static_cast<uint16_t>(src.path.size());
   dst->extra_field_length = src.padding_length;
 }
 
@@ -203,6 +204,11 @@
     return kInvalidState;
   }
 
+  // Can only have 16535 entries because of zip records.
+  if (files_.size() == std::numeric_limits<uint16_t>::max()) {
+    return HandleError(kIoError);
+  }
+
   if (flags & kAlign32) {
     return kInvalidAlign32Flag;
   }
@@ -210,10 +216,17 @@
   if (powerof2(alignment) == 0) {
     return kInvalidAlignment;
   }
+  if (alignment > std::numeric_limits<uint16_t>::max()) {
+    return kInvalidAlignment;
+  }
 
   FileEntry file_entry = {};
   file_entry.local_file_header_offset = current_offset_;
   file_entry.path = path;
+  // No support for larger than 4GB files.
+  if (file_entry.local_file_header_offset > std::numeric_limits<uint32_t>::max()) {
+    return HandleError(kIoError);
+  }
 
   if (!IsValidEntryName(reinterpret_cast<const uint8_t*>(file_entry.path.data()),
                         file_entry.path.size())) {
@@ -237,7 +250,7 @@
   std::vector<char> zero_padding;
   if (alignment != 0 && (offset & (alignment - 1))) {
     // Pad the extra field so the data will be aligned.
-    uint16_t padding = alignment - (offset % alignment);
+    uint16_t padding = static_cast<uint16_t>(alignment - (offset % alignment));
     file_entry.padding_length = padding;
     offset += padding;
     zero_padding.resize(padding, 0);
@@ -314,7 +327,8 @@
   }
 
   z_stream_->next_out = buffer_.data();
-  z_stream_->avail_out = buffer_.size();
+  DCHECK_EQ(buffer_.size(), kBufSize);
+  z_stream_->avail_out = static_cast<uint32_t>(buffer_.size());
   return kNoError;
 }
 
@@ -322,25 +336,31 @@
   if (state_ != State::kWritingEntry) {
     return HandleError(kInvalidState);
   }
+  // Need to be able to mark down data correctly.
+  if (len + static_cast<uint64_t>(current_file_entry_.uncompressed_size) >
+      std::numeric_limits<uint32_t>::max()) {
+    return HandleError(kIoError);
+  }
+  uint32_t len32 = static_cast<uint32_t>(len);
 
   int32_t result = kNoError;
   if (current_file_entry_.compression_method & kCompressDeflated) {
-    result = CompressBytes(&current_file_entry_, data, len);
+    result = CompressBytes(&current_file_entry_, data, len32);
   } else {
-    result = StoreBytes(&current_file_entry_, data, len);
+    result = StoreBytes(&current_file_entry_, data, len32);
   }
 
   if (result != kNoError) {
     return result;
   }
 
-  current_file_entry_.crc32 =
-      crc32(current_file_entry_.crc32, reinterpret_cast<const Bytef*>(data), len);
-  current_file_entry_.uncompressed_size += len;
+  current_file_entry_.crc32 = static_cast<uint32_t>(
+      crc32(current_file_entry_.crc32, reinterpret_cast<const Bytef*>(data), len32));
+  current_file_entry_.uncompressed_size += len32;
   return kNoError;
 }
 
-int32_t ZipWriter::StoreBytes(FileEntry* file, const void* data, size_t len) {
+int32_t ZipWriter::StoreBytes(FileEntry* file, const void* data, uint32_t len) {
   CHECK(state_ == State::kWritingEntry);
 
   if (fwrite(data, 1, len, file_) != len) {
@@ -351,7 +371,7 @@
   return kNoError;
 }
 
-int32_t ZipWriter::CompressBytes(FileEntry* file, const void* data, size_t len) {
+int32_t ZipWriter::CompressBytes(FileEntry* file, const void* data, uint32_t len) {
   CHECK(state_ == State::kWritingEntry);
   CHECK(z_stream_);
   CHECK(z_stream_->next_out != nullptr);
@@ -379,7 +399,8 @@
 
       // Reset the output buffer for the next input.
       z_stream_->next_out = buffer_.data();
-      z_stream_->avail_out = buffer_.size();
+      DCHECK_EQ(buffer_.size(), kBufSize);
+      z_stream_->avail_out = static_cast<uint32_t>(buffer_.size());
     }
   }
   return kNoError;
@@ -404,7 +425,8 @@
     current_offset_ += write_bytes;
 
     z_stream_->next_out = buffer_.data();
-    z_stream_->avail_out = buffer_.size();
+    DCHECK_EQ(buffer_.size(), kBufSize);
+    z_stream_->avail_out = static_cast<uint32_t>(buffer_.size());
   }
   if (zerr != Z_STREAM_END) {
     return HandleError(kZlibError);
@@ -491,7 +513,11 @@
     cdr.crc32 = file.crc32;
     cdr.compressed_size = file.compressed_size;
     cdr.uncompressed_size = file.uncompressed_size;
-    cdr.file_name_length = file.path.size();
+    // Checked in IsValidEntryName.
+    DCHECK_LE(file.path.size(), std::numeric_limits<uint16_t>::max());
+    cdr.file_name_length = static_cast<uint16_t>(file.path.size());
+    // Checked in StartAlignedEntryWithTime.
+    DCHECK_LE(file.local_file_header_offset, std::numeric_limits<uint32_t>::max());
     cdr.local_file_header_offset = static_cast<uint32_t>(file.local_file_header_offset);
     if (fwrite(&cdr, sizeof(cdr), 1, file_) != 1) {
       return HandleError(kIoError);
@@ -508,10 +534,15 @@
   er.eocd_signature = EocdRecord::kSignature;
   er.disk_num = 0;
   er.cd_start_disk = 0;
-  er.num_records_on_disk = files_.size();
-  er.num_records = files_.size();
-  er.cd_size = current_offset_ - startOfCdr;
-  er.cd_start_offset = startOfCdr;
+  // Checked when adding entries.
+  DCHECK_LE(files_.size(), std::numeric_limits<uint16_t>::max());
+  er.num_records_on_disk = static_cast<uint16_t>(files_.size());
+  er.num_records = static_cast<uint16_t>(files_.size());
+  if (current_offset_ > std::numeric_limits<uint32_t>::max()) {
+    return HandleError(kIoError);
+  }
+  er.cd_size = static_cast<uint32_t>(current_offset_ - startOfCdr);
+  er.cd_start_offset = static_cast<uint32_t>(startOfCdr);
 
   if (fwrite(&er, sizeof(er), 1, file_) != 1) {
     return HandleError(kIoError);
diff --git a/libziparchive/zip_writer_test.cc b/libziparchive/zip_writer_test.cc
index 7322afb..63adbbc 100644
--- a/libziparchive/zip_writer_test.cc
+++ b/libziparchive/zip_writer_test.cc
@@ -279,7 +279,8 @@
 
   std::vector<uint8_t> decompress(kBufSize);
   memset(decompress.data(), 0, kBufSize);
-  ASSERT_EQ(0, ExtractToMemory(handle, &data, decompress.data(), decompress.size()));
+  ASSERT_EQ(0, ExtractToMemory(handle, &data, decompress.data(),
+                               static_cast<uint32_t>(decompress.size())));
   EXPECT_EQ(0, memcmp(decompress.data(), buffer.data(), kBufSize))
       << "Input buffer and output buffer are different.";
 
@@ -391,7 +392,7 @@
   actual.resize(expected.size());
 
   uint8_t* buffer = reinterpret_cast<uint8_t*>(&*actual.begin());
-  if (ExtractToMemory(handle, zip_entry, buffer, actual.size()) != 0) {
+  if (ExtractToMemory(handle, zip_entry, buffer, static_cast<uint32_t>(actual.size())) != 0) {
     return ::testing::AssertionFailure() << "failed to extract entry";
   }
 
diff --git a/rootdir/etc/ld.config.legacy.txt b/rootdir/etc/ld.config.legacy.txt
index 8792671..e081bdf 100644
--- a/rootdir/etc/ld.config.legacy.txt
+++ b/rootdir/etc/ld.config.legacy.txt
@@ -99,7 +99,6 @@
 namespace.media.permitted.paths = /apex/com.android.media/${LIB}/extractors
 
 namespace.media.links = default
-namespace.media.link.default.shared_libs  = libandroid.so
 namespace.media.link.default.shared_libs += libbinder_ndk.so
 namespace.media.link.default.shared_libs += libc.so
 namespace.media.link.default.shared_libs += libcgrouprc.so
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index b486411..3f9882a 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -179,7 +179,6 @@
 
 namespace.media.links = default
 namespace.media.link.default.shared_libs  = %LLNDK_LIBRARIES%
-namespace.media.link.default.shared_libs += libandroid.so
 namespace.media.link.default.shared_libs += libbinder_ndk.so
 namespace.media.link.default.shared_libs += libmediametrics.so
 namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -622,7 +621,6 @@
 
 namespace.media.links = default
 namespace.media.link.default.shared_libs  = %LLNDK_LIBRARIES%
-namespace.media.link.default.shared_libs += libandroid.so
 namespace.media.link.default.shared_libs += libbinder_ndk.so
 namespace.media.link.default.shared_libs += libmediametrics.so
 namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index 12007dc..6d89886 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -121,7 +121,6 @@
 
 namespace.media.links = default
 namespace.media.link.default.shared_libs  = %LLNDK_LIBRARIES%
-namespace.media.link.default.shared_libs += libandroid.so
 namespace.media.link.default.shared_libs += libbinder_ndk.so
 namespace.media.link.default.shared_libs += libmediametrics.so
 namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -445,7 +444,6 @@
 
 namespace.media.links = default
 namespace.media.link.default.shared_libs  = %LLNDK_LIBRARIES%
-namespace.media.link.default.shared_libs += libandroid.so
 namespace.media.link.default.shared_libs += libbinder_ndk.so
 namespace.media.link.default.shared_libs += libmediametrics.so
 namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
diff --git a/rootdir/init.rc b/rootdir/init.rc
index e94b8e2..9bb624a 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -13,9 +13,6 @@
 
 # Cgroups are mounted right before early-init using list from /etc/cgroups.json
 on early-init
-    # Set init and its forked children's oom_adj.
-    write /proc/1/oom_score_adj -1000
-
     # Disable sysrq from keyboard
     write /proc/sys/kernel/sysrq 0