Merge "fs_mgr: support reading fstab based on ro.boot.hardware.platform"
diff --git a/base/Android.bp b/base/Android.bp
index f4a8411..7ff02a0 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -14,11 +14,10 @@
 // limitations under the License.
 //
 
-libbase_cppflags = [
-    "-Wall",
-    "-Wextra",
-    "-Werror",
-]
+cc_defaults {
+    name: "libbase_defaults",
+    cflags: ["-Wall", "-Werror", "-Wextra"],
+}
 
 cc_library_headers {
     name: "libbase_headers",
@@ -38,6 +37,7 @@
 
 cc_library {
     name: "libbase",
+    defaults: ["libbase_defaults"],
     vendor_available: true,
     host_supported: true,
     vndk: {
@@ -59,7 +59,6 @@
     ],
     export_header_lib_headers: ["libbase_headers"],
 
-    cppflags: libbase_cppflags,
     shared_libs: ["liblog"],
     target: {
         android: {
@@ -102,6 +101,7 @@
 // ------------------------------------------------------------------------------
 cc_test {
     name: "libbase_test",
+    defaults: ["libbase_defaults"],
     host_supported: true,
     srcs: [
         "endian_test.cpp",
@@ -133,7 +133,6 @@
         },
     },
     local_include_dirs: ["."],
-    cppflags: libbase_cppflags,
     shared_libs: ["libbase"],
     compile_multilib: "both",
     multilib: {
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 10753ce..8c11289 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -227,6 +227,7 @@
     {"shutdown,thermal,battery", 87},
     {"reboot,its_just_so_hard", 88},  // produced by boot_reason_test
     {"reboot,Its Just So Hard", 89},  // produced by boot_reason_test
+    {"usb", 90},
 };
 
 // Converts a string value representing the reason the system booted to an
diff --git a/debuggerd/crasher/Android.bp b/debuggerd/crasher/Android.bp
index 67b4ab7..7bec470 100644
--- a/debuggerd/crasher/Android.bp
+++ b/debuggerd/crasher/Android.bp
@@ -1,7 +1,7 @@
 cc_defaults {
     name: "crasher-defaults",
 
-    cppflags: [
+    cflags: [
         "-W",
         "-Wall",
         "-Wextra",
diff --git a/demangle/DemangleTest.cpp b/demangle/DemangleTest.cpp
index c93e2ab..5825e6c 100644
--- a/demangle/DemangleTest.cpp
+++ b/demangle/DemangleTest.cpp
@@ -334,6 +334,29 @@
   // Template within templates.
   ASSERT_EQ("one::two<three<char, int>>", demangler.Parse("_ZN3one3twoIN5threeIciEEEE"));
   ASSERT_EQ("one::two<three<char, four<int>>>", demangler.Parse("_ZN3one3twoIN5threeIcN4fourIiEEEEEE"));
+
+  ASSERT_EQ("one<char>", demangler.Parse("_Z3oneIcE"));
+  ASSERT_EQ("one<void>", demangler.Parse("_Z3oneIvE"));
+  ASSERT_EQ("one<void*>", demangler.Parse("_Z3oneIPvE"));
+  ASSERT_EQ("one<void const>", demangler.Parse("_Z3oneIKvE"));
+  ASSERT_EQ("one<char, int, bool>", demangler.Parse("_Z3oneIcibE"));
+  ASSERT_EQ("one(two<three>)", demangler.Parse("_Z3one3twoIN5threeEE"));
+  ASSERT_EQ("one<char, int, two::three>", demangler.Parse("_Z3oneIciN3two5threeEE"));
+  // Template within templates.
+  ASSERT_EQ("one(two<three<char, int>>)", demangler.Parse("_Z3one3twoIN5threeIciEEE"));
+  ASSERT_EQ("one(two<three<char, four<int>>>)",
+            demangler.Parse("_Z3one3twoIN5threeIcN4fourIiEEEEE"));
+}
+
+TEST(DemangleTest, TemplateFunctionWithReturnType) {
+  Demangler demangler;
+
+  ASSERT_EQ("char one<int>(char)", demangler.Parse("_Z3oneIiEcc"));
+  ASSERT_EQ("void one<int>()", demangler.Parse("_Z3oneIiEvv"));
+  ASSERT_EQ("char one<int>()", demangler.Parse("_Z3oneIiEcv"));
+  ASSERT_EQ("char one<int>(void, void)", demangler.Parse("_Z3oneIiEcvv"));
+  ASSERT_EQ("char one<int>()", demangler.Parse("_ZN3oneIiEEcv"));
+  ASSERT_EQ("char one<int>(void, void)", demangler.Parse("_ZN3oneIiEEcvv"));
 }
 
 TEST(DemangleTest, TemplateArguments) {
@@ -410,6 +433,28 @@
             demangler.Parse("_ZN3one3two5three4fourINS_4fiveEED2EPS3_"));
 }
 
+TEST(DemangleTest, TemplateSubstitution) {
+  Demangler demangler;
+
+  ASSERT_EQ("void one<int, double>(int)", demangler.Parse("_ZN3oneIidEEvT_"));
+  ASSERT_EQ("void one<int, double>(double)", demangler.Parse("_ZN3oneIidEEvT0_"));
+  ASSERT_EQ("void one<int, double, char, void>(char)", demangler.Parse("_ZN3oneIidcvEEvT1_"));
+
+  ASSERT_EQ("void one<int, double>(int)", demangler.Parse("_Z3oneIidEvT_"));
+  ASSERT_EQ("void one<int, double>(double)", demangler.Parse("_Z3oneIidEvT0_"));
+  ASSERT_EQ("void one<int, double, char, void>(char)", demangler.Parse("_Z3oneIidcvEvT1_"));
+
+  ASSERT_EQ("void one<a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r>(l)",
+            demangler.Parse("_ZN3oneI1a1b1c1d1e1f1g1h1i1j1k1l1m1n1o1p1q1rEEvT10_"));
+  ASSERT_EQ("void one<a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r>(m)",
+            demangler.Parse("_ZN3oneI1a1b1c1d1e1f1g1h1i1j1k1l1m1n1o1p1q1rEEvT11_"));
+
+  ASSERT_EQ("void one<a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r>(l)",
+            demangler.Parse("_Z3oneI1a1b1c1d1e1f1g1h1i1j1k1l1m1n1o1p1q1rEvT10_"));
+  ASSERT_EQ("void one<a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r>(m)",
+            demangler.Parse("_Z3oneI1a1b1c1d1e1f1g1h1i1j1k1l1m1n1o1p1q1rEvT11_"));
+}
+
 TEST(DemangleTest, StringTooLong) {
   Demangler demangler;
 
@@ -434,6 +479,13 @@
   ASSERT_EQ("one<true>", demangler.Parse("_ZN3oneILb1EEE"));
   ASSERT_EQ("one<false>", demangler.Parse("_ZN3oneILb0EEE"));
   ASSERT_EQ("one<false, true>", demangler.Parse("_ZN3oneILb0ELb1EEE"));
+
+  ASSERT_EQ("one<true>", demangler.Parse("_Z3oneILb1EE"));
+  ASSERT_EQ("one<false>", demangler.Parse("_Z3oneILb0EE"));
+  ASSERT_EQ("one<false, true>", demangler.Parse("_Z3oneILb0ELb1EE"));
+
+  ASSERT_EQ("one(two<three<four>, false, true>)",
+            demangler.Parse("_ZN3oneE3twoI5threeI4fourELb0ELb1EE"));
 }
 
 TEST(DemangleTest, demangle) {
diff --git a/demangle/Demangler.cpp b/demangle/Demangler.cpp
index f148b21..18a90b4 100644
--- a/demangle/Demangler.cpp
+++ b/demangle/Demangler.cpp
@@ -347,6 +347,33 @@
   return name + 1;
 }
 
+const char* Demangler::ParseT(const char* name) {
+  if (template_saves_.empty()) {
+    return nullptr;
+  }
+
+  if (*name == '_') {
+    last_save_name_ = false;
+    AppendCurrent(template_saves_[0]);
+    return name + 1;
+  }
+
+  // Need to get the total number.
+  char* end;
+  unsigned long int index = strtoul(name, &end, 10) + 1;
+  if (name == end || *end != '_') {
+    return nullptr;
+  }
+
+  if (index >= template_saves_.size()) {
+    return nullptr;
+  }
+
+  last_save_name_ = false;
+  AppendCurrent(template_saves_[index]);
+  return end + 1;
+}
+
 const char* Demangler::ParseFunctionName(const char* name) {
   if (*name == 'E') {
     if (parse_funcs_.empty()) {
@@ -371,9 +398,28 @@
     return name + 1;
   }
 
+  if (*name == 'I') {
+    state_stack_.push(cur_state_);
+    cur_state_.Clear();
+
+    parse_funcs_.push_back(parse_func_);
+    parse_func_ = &Demangler::ParseFunctionNameTemplate;
+    return name + 1;
+  }
+
   return ParseComplexString(name);
 }
 
+const char* Demangler::ParseFunctionNameTemplate(const char* name) {
+  if (*name == 'E' && name[1] == 'E') {
+    // Only consider this a template with saves if it is right before
+    // the end of the name.
+    template_found_ = true;
+    template_saves_ = cur_state_.args;
+  }
+  return ParseTemplateArgumentsComplex(name);
+}
+
 const char* Demangler::ParseComplexArgument(const char* name) {
   if (*name == 'E') {
     if (parse_funcs_.empty()) {
@@ -690,6 +736,7 @@
     }
     parse_func_ = parse_funcs_.back();
     parse_funcs_.pop_back();
+
     FinalizeTemplate();
     Save(cur_state_.str, false);
     return name + 1;
@@ -699,6 +746,7 @@
     parse_func_ = &Demangler::ParseTemplateLiteral;
     return name + 1;
   }
+
   return ParseArguments(name);
 }
 
@@ -713,13 +761,33 @@
     AppendArgument(cur_state_.str);
     cur_state_.str.clear();
     return name + 1;
+  } else if (*name == 'L') {
+    // Literal value for a template.
+    parse_funcs_.push_back(parse_func_);
+    parse_func_ = &Demangler::ParseTemplateLiteral;
+    return name + 1;
   }
+
   return ParseArguments(name);
 }
 
+const char* Demangler::ParseFunctionTemplateArguments(const char* name) {
+  if (*name == 'E') {
+    parse_func_ = parse_funcs_.back();
+    parse_funcs_.pop_back();
+
+    function_name_ += '<' + GetArgumentsString() + '>';
+    template_found_ = true;
+    template_saves_ = cur_state_.args;
+    cur_state_.Clear();
+    return name + 1;
+  }
+  return ParseTemplateArgumentsComplex(name);
+}
+
 const char* Demangler::FindFunctionName(const char* name) {
   if (*name == 'N') {
-    parse_funcs_.push_back(&Demangler::ParseArguments);
+    parse_funcs_.push_back(&Demangler::ParseArgumentsAtTopLevel);
     parse_func_ = &Demangler::ParseFunctionName;
     return name + 1;
   }
@@ -732,11 +800,35 @@
     name = AppendOperatorString(name);
     function_name_ = cur_state_.str;
   }
-  parse_func_ = &Demangler::ParseArguments;
   cur_state_.Clear();
+
+  // Check for a template argument, which will still be part of the function
+  // name.
+  if (name != nullptr && *name == 'I') {
+    parse_funcs_.push_back(&Demangler::ParseArgumentsAtTopLevel);
+    parse_func_ = &Demangler::ParseFunctionTemplateArguments;
+    return name + 1;
+  }
+  parse_func_ = &Demangler::ParseArgumentsAtTopLevel;
   return name;
 }
 
+const char* Demangler::ParseArgumentsAtTopLevel(const char* name) {
+  // At the top level is the only place where T is allowed.
+  if (*name == 'T') {
+    name++;
+    name = ParseT(name);
+    if (name == nullptr) {
+      return nullptr;
+    }
+    AppendArgument(cur_state_.str);
+    cur_state_.str.clear();
+    return name;
+  }
+
+  return Demangler::ParseArguments(name);
+}
+
 std::string Demangler::Parse(const char* name, size_t max_length) {
   if (name[0] == '\0' || name[0] != '_' || name[1] == '\0' || name[1] != 'Z') {
     // Name is not mangled.
@@ -757,6 +849,21 @@
     return name;
   }
 
+  std::string return_type;
+  if (template_found_) {
+    // Only a single argument with a template is not allowed.
+    if (cur_state_.args.size() == 1) {
+      return name;
+    }
+
+    // If there are at least two arguments, this template has a return type.
+    if (cur_state_.args.size() > 1) {
+      // The first argument will be the return value.
+      return_type = cur_state_.args[0] + ' ';
+      cur_state_.args.erase(cur_state_.args.begin());
+    }
+  }
+
   std::string arg_str;
   if (cur_state_.args.size() == 1 && cur_state_.args[0] == "void") {
     // If the only argument is void, then don't print any args.
@@ -767,7 +874,7 @@
       arg_str = '(' + arg_str + ')';
     }
   }
-  return function_name_ + arg_str + function_suffix_;
+  return return_type + function_name_ + arg_str + function_suffix_;
 }
 
 std::string demangle(const char* name) {
diff --git a/demangle/Demangler.h b/demangle/Demangler.h
index f76def6..3b7d44e 100644
--- a/demangle/Demangler.h
+++ b/demangle/Demangler.h
@@ -39,6 +39,7 @@
   std::string GetArgumentsString();
   void FinalizeTemplate();
   const char* ParseS(const char* name);
+  const char* ParseT(const char* name);
   const char* AppendOperatorString(const char* name);
   void Save(const std::string& str, bool is_name);
 
@@ -50,17 +51,21 @@
     first_save_.clear();
     cur_state_.Clear();
     saves_.clear();
+    template_saves_.clear();
     while (!state_stack_.empty()) {
       state_stack_.pop();
     }
     last_save_name_ = false;
+    template_found_ = false;
   }
 
   using parse_func_type = const char* (Demangler::*)(const char*);
   parse_func_type parse_func_;
   std::vector<parse_func_type> parse_funcs_;
   std::vector<std::string> saves_;
+  std::vector<std::string> template_saves_;
   bool last_save_name_;
+  bool template_found_;
 
   std::string function_name_;
   std::string function_suffix_;
@@ -89,12 +94,15 @@
   // Parsing functions.
   const char* ParseComplexString(const char* name);
   const char* ParseComplexArgument(const char* name);
+  const char* ParseArgumentsAtTopLevel(const char* name);
   const char* ParseArguments(const char* name);
   const char* ParseTemplateArguments(const char* name);
   const char* ParseTemplateArgumentsComplex(const char* name);
   const char* ParseTemplateLiteral(const char* name);
   const char* ParseFunctionArgument(const char* name);
   const char* ParseFunctionName(const char* name);
+  const char* ParseFunctionNameTemplate(const char* name);
+  const char* ParseFunctionTemplateArguments(const char* name);
   const char* FindFunctionName(const char* name);
   const char* Fail(const char*) { return nullptr; }
 
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index 5a6298e..ed165ed 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -20,7 +20,11 @@
         misc_undefined: ["integer"],
     },
     local_include_dirs: ["include/"],
-    cppflags: ["-Werror"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-unused-variable",
+    ],
 }
 
 cc_library_static {
diff --git a/init/Android.bp b/init/Android.bp
index 8c4f005..45ee754 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -20,7 +20,7 @@
     sanitize: {
         misc_undefined: ["signed-integer-overflow"],
     },
-    cppflags: [
+    cflags: [
         "-DLOG_UEVENTS=0",
         "-Wall",
         "-Wextra",
diff --git a/init/test_service/Android.bp b/init/test_service/Android.bp
index 9bd6f27..6399699 100644
--- a/init/test_service/Android.bp
+++ b/init/test_service/Android.bp
@@ -17,6 +17,7 @@
 cc_binary {
     name: "test_service",
     srcs: ["test_service.cpp"],
+    cflags: ["-Wall", "-Werror"],
     shared_libs: ["libbase"],
     init_rc: ["test_service.rc"],
 }
diff --git a/init/test_service/test_service.cpp b/init/test_service/test_service.cpp
index e7206f8..71d1ea4 100644
--- a/init/test_service/test_service.cpp
+++ b/init/test_service/test_service.cpp
@@ -59,7 +59,6 @@
     }
 
     bool test_fails = false;
-    size_t uargc = static_cast<size_t>(argc);  // |argc| >= 3.
     for (size_t i = 1; i < static_cast<size_t>(argc); i = i + 2) {
         std::string expected_value = argv[i + 1];
         auto f = fields.find(argv[i]);
diff --git a/libasyncio/Android.bp b/libasyncio/Android.bp
index 9a637ac..9a12f0d 100644
--- a/libasyncio/Android.bp
+++ b/libasyncio/Android.bp
@@ -14,20 +14,19 @@
 // limitations under the License.
 //
 
-libasyncio_cppflags = [
-    "-Wall",
-    "-Wextra",
-    "-Werror",
-]
+cc_defaults {
+    name: "libasyncio_defaults",
+    cflags: ["-Wall", "-Werror", "-Wextra"],
+}
 
 cc_library {
     name: "libasyncio",
+    defaults: ["libasyncio_defaults"],
     vendor_available: true,
     host_supported: true,
     srcs: [
         "AsyncIO.cpp",
     ],
-    cppflags: libasyncio_cppflags,
 
     export_include_dirs: ["include"],
     target: {
diff --git a/libgrallocusage/Android.bp b/libgrallocusage/Android.bp
index cf03868..bcc0616 100644
--- a/libgrallocusage/Android.bp
+++ b/libgrallocusage/Android.bp
@@ -15,9 +15,12 @@
 cc_library_static {
     name: "libgrallocusage",
     vendor_available: true,
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
     cppflags: [
         "-Weverything",
-        "-Werror",
         "-Wno-c++98-compat-pedantic",
         // Hide errors in headers we include
         "-Wno-global-constructors",
diff --git a/libnativebridge/tests/Android.mk b/libnativebridge/tests/Android.mk
index b3861e0..5b9ba1c 100644
--- a/libnativebridge/tests/Android.mk
+++ b/libnativebridge/tests/Android.mk
@@ -33,10 +33,15 @@
     libnativebridge \
     libnativebridge-dummy
 
+libnativebridge_tests_common_cflags := \
+    -Wall \
+    -Werror \
+
 $(foreach file,$(test_src_files), \
     $(eval include $(CLEAR_VARS)) \
     $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
     $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_CFLAGS := $(libnativebridge_tests_common_cflags)) \
     $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
     $(eval include $(BUILD_NATIVE_TEST)) \
 )
@@ -45,6 +50,7 @@
     $(eval include $(CLEAR_VARS)) \
     $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
     $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_CFLAGS := $(libnativebridge_tests_common_cflags)) \
     $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
     $(eval include $(BUILD_HOST_NATIVE_TEST)) \
 )
diff --git a/libnativebridge/tests/PreInitializeNativeBridge_test.cpp b/libnativebridge/tests/PreInitializeNativeBridge_test.cpp
index f3e5f38..cd5a8e2 100644
--- a/libnativebridge/tests/PreInitializeNativeBridge_test.cpp
+++ b/libnativebridge/tests/PreInitializeNativeBridge_test.cpp
@@ -30,12 +30,12 @@
 
 namespace android {
 
-static constexpr const char* kTestData = "PreInitializeNativeBridge test.";
-
 TEST_F(NativeBridgeTest, PreInitializeNativeBridge) {
     ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr));
 #if !defined(__APPLE__)         // Mac OS does not support bind-mount.
 #if !defined(__ANDROID__)       // Cannot write into the hard-wired location.
+    static constexpr const char* kTestData = "PreInitializeNativeBridge test.";
+
     // Try to create our mount namespace.
     if (unshare(CLONE_NEWNS) != -1) {
         // Create a dummy file.
diff --git a/libpackagelistparser/Android.bp b/libpackagelistparser/Android.bp
index a9fec7d..3d202fc 100644
--- a/libpackagelistparser/Android.bp
+++ b/libpackagelistparser/Android.bp
@@ -2,6 +2,7 @@
 
     name: "libpackagelistparser",
     srcs: ["packagelistparser.c"],
+    cflags: ["-Wall", "-Werror"],
     shared_libs: ["liblog"],
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
diff --git a/libprocinfo/Android.bp b/libprocinfo/Android.bp
index b568ee5..1cfabd5 100644
--- a/libprocinfo/Android.bp
+++ b/libprocinfo/Android.bp
@@ -14,14 +14,14 @@
 // limitations under the License.
 //
 
-libprocinfo_cppflags = [
-    "-Wall",
-    "-Wextra",
-    "-Werror",
-]
+cc_defaults {
+    name: "libprocinfo_defaults",
+    cflags: ["-Wall", "-Werror", "-Wextra"],
+}
 
 cc_library {
     name: "libprocinfo",
+    defaults: ["libprocinfo_defaults"],
     vendor_available: true,
     vndk: {
         enabled: true,
@@ -30,7 +30,6 @@
     srcs: [
         "process.cpp",
     ],
-    cppflags: libprocinfo_cppflags,
 
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
@@ -52,6 +51,7 @@
 // ------------------------------------------------------------------------------
 cc_test {
     name: "libprocinfo_test",
+    defaults: ["libprocinfo_defaults"],
     host_supported: true,
     srcs: [
         "process_test.cpp",
@@ -65,7 +65,6 @@
         },
     },
 
-    cppflags: libprocinfo_cppflags,
     shared_libs: ["libbase", "libprocinfo"],
 
     compile_multilib: "both",
diff --git a/libunwindstack/DwarfSection.cpp b/libunwindstack/DwarfSection.cpp
index b8164c5..2292168 100644
--- a/libunwindstack/DwarfSection.cpp
+++ b/libunwindstack/DwarfSection.cpp
@@ -107,7 +107,6 @@
     return false;
   }
 
-  AddressType prev_pc = regs->pc();
   AddressType prev_cfa = regs->sp();
 
   AddressType cfa;
@@ -233,8 +232,8 @@
   *finished = (cur_regs->pc() == 0) ? true : false;
 
   cur_regs->set_sp(cfa);
-  // Return false if the unwind is not finished or the cfa and pc didn't change.
-  return *finished || prev_cfa != cfa || prev_pc != cur_regs->pc();
+
+  return true;
 }
 
 template <typename AddressType>
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp
index 2190711..2e46a11 100644
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -87,8 +87,10 @@
   bool return_address_attempt = false;
   bool adjust_pc = false;
   for (; frames_.size() < max_frames_;) {
-    MapInfo* map_info = maps_->Find(regs_->pc());
+    uint64_t cur_pc = regs_->pc();
+    uint64_t cur_sp = regs_->sp();
 
+    MapInfo* map_info = maps_->Find(regs_->pc());
     uint64_t rel_pc;
     Elf* elf;
     if (map_info == nullptr) {
@@ -138,6 +140,7 @@
         }
       }
     }
+
     if (!stepped) {
       if (return_address_attempt) {
         // Remove the speculative frame.
@@ -157,6 +160,11 @@
     } else {
       return_address_attempt = false;
     }
+
+    // If the pc and sp didn't change, then consider everything stopped.
+    if (cur_pc == regs_->pc() && cur_sp == regs_->sp()) {
+      break;
+    }
   }
 }
 
diff --git a/libunwindstack/tests/DwarfSectionImplTest.cpp b/libunwindstack/tests/DwarfSectionImplTest.cpp
index 7e85bbb..5b9f3ee 100644
--- a/libunwindstack/tests/DwarfSectionImplTest.cpp
+++ b/libunwindstack/tests/DwarfSectionImplTest.cpp
@@ -431,22 +431,6 @@
   EXPECT_EQ(0x80000000U, regs.pc());
 }
 
-TYPED_TEST_P(DwarfSectionImplTest, Eval_same_cfa_same_pc) {
-  DwarfCie cie{.version = 3, .return_address_register = 5};
-  RegsImplFake<TypeParam> regs(10, 9);
-  dwarf_loc_regs_t loc_regs;
-
-  regs.set_pc(0x100);
-  regs.set_sp(0x2000);
-  regs[5] = 0x100;
-  regs[8] = 0x2000;
-  loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
-  bool finished;
-  ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
-  EXPECT_EQ(0x2000U, regs.sp());
-  EXPECT_EQ(0x100U, regs.pc());
-}
-
 TYPED_TEST_P(DwarfSectionImplTest, GetCie_fail_should_not_cache) {
   ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr);
   EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->last_error());
@@ -872,9 +856,9 @@
     Eval_cfa_bad, Eval_cfa_register_prev, Eval_cfa_register_from_value, Eval_double_indirection,
     Eval_invalid_register, Eval_different_reg_locations, Eval_return_address_undefined,
     Eval_pc_zero, Eval_return_address, Eval_ignore_large_reg_loc, Eval_reg_expr, Eval_reg_val_expr,
-    Eval_same_cfa_same_pc, GetCie_fail_should_not_cache, GetCie_32_version_check,
-    GetCie_negative_data_alignment_factor, GetCie_64_no_augment, GetCie_augment, GetCie_version_3,
-    GetCie_version_4, GetFdeFromOffset_fail_should_not_cache, GetFdeFromOffset_32_no_augment,
+    GetCie_fail_should_not_cache, GetCie_32_version_check, GetCie_negative_data_alignment_factor,
+    GetCie_64_no_augment, GetCie_augment, GetCie_version_3, GetCie_version_4,
+    GetFdeFromOffset_fail_should_not_cache, GetFdeFromOffset_32_no_augment,
     GetFdeFromOffset_32_no_augment_non_zero_segment_size, GetFdeFromOffset_32_augment,
     GetFdeFromOffset_64_no_augment, GetFdeFromOffset_cached, GetCfaLocationInfo_cie_not_cached,
     GetCfaLocationInfo_cie_cached, Log);
diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp
index 8a90bae..869d118 100644
--- a/libunwindstack/tests/UnwinderTest.cpp
+++ b/libunwindstack/tests/UnwinderTest.cpp
@@ -127,6 +127,7 @@
   void SetUp() override {
     ElfInterfaceFake::FakeClear();
     regs_.FakeSetMachineType(EM_ARM);
+    regs_.FakeSetReturnAddressValid(false);
   }
 
   static MapsFake maps_;
@@ -610,6 +611,71 @@
   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
 }
 
+// Verify that an unwind stops when the sp and pc don't change.
+TEST_F(UnwinderTest, sp_pc_do_not_change) {
+  ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
+  ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
+  ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
+  ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
+  ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
+
+  regs_.FakeSetPc(0x1000);
+  regs_.FakeSetSp(0x10000);
+  ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
+  ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
+  ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
+  ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
+  ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
+  ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
+
+  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  unwinder.Unwind();
+
+  ASSERT_EQ(3U, unwinder.NumFrames());
+
+  auto* frame = &unwinder.frames()[0];
+  EXPECT_EQ(0U, frame->num);
+  EXPECT_EQ(0U, frame->rel_pc);
+  EXPECT_EQ(0x1000U, frame->pc);
+  EXPECT_EQ(0x10000U, frame->sp);
+  EXPECT_EQ("Frame0", frame->function_name);
+  EXPECT_EQ(0U, frame->function_offset);
+  EXPECT_EQ("/system/fake/libc.so", frame->map_name);
+  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0x1000U, frame->map_start);
+  EXPECT_EQ(0x8000U, frame->map_end);
+  EXPECT_EQ(0U, frame->map_load_bias);
+  EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
+
+  frame = &unwinder.frames()[1];
+  EXPECT_EQ(1U, frame->num);
+  EXPECT_EQ(0x400U, frame->rel_pc);
+  EXPECT_EQ(0x33400U, frame->pc);
+  EXPECT_EQ(0x10010U, frame->sp);
+  EXPECT_EQ("Frame1", frame->function_name);
+  EXPECT_EQ(1U, frame->function_offset);
+  EXPECT_EQ("/fake/compressed.so", frame->map_name);
+  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0x33000U, frame->map_start);
+  EXPECT_EQ(0x34000U, frame->map_end);
+  EXPECT_EQ(0U, frame->map_load_bias);
+  EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
+
+  frame = &unwinder.frames()[2];
+  EXPECT_EQ(2U, frame->num);
+  EXPECT_EQ(0x500U, frame->rel_pc);
+  EXPECT_EQ(0x33500U, frame->pc);
+  EXPECT_EQ(0x10020U, frame->sp);
+  EXPECT_EQ("Frame2", frame->function_name);
+  EXPECT_EQ(2U, frame->function_offset);
+  EXPECT_EQ("/fake/compressed.so", frame->map_name);
+  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0x33000U, frame->map_start);
+  EXPECT_EQ(0x34000U, frame->map_end);
+  EXPECT_EQ(0U, frame->map_load_bias);
+  EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
+}
+
 // Verify format frame code.
 TEST_F(UnwinderTest, format_frame_static) {
   FrameData frame;
diff --git a/libutils/Android.bp b/libutils/Android.bp
index b70845b..4bd2a98 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -75,7 +75,7 @@
         "misc.cpp",
     ],
 
-    cflags: ["-Werror"],
+    cflags: ["-Wall", "-Werror"],
     include_dirs: ["external/safe-iop/include"],
     header_libs: [
         "libutils_headers",
@@ -154,6 +154,7 @@
     static_libs: ["libutils"],
     shared_libs: ["liblog"],
     srcs: ["SharedBufferTest.cpp"],
+    cflags: ["-Wall", "-Werror"],
 }
 
 subdirs = ["tests"]
diff --git a/libutils/RefBase.cpp b/libutils/RefBase.cpp
index f5f881f..8bccb0f 100644
--- a/libutils/RefBase.cpp
+++ b/libutils/RefBase.cpp
@@ -410,8 +410,7 @@
         return;
     }
 
-    int32_t old = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
-            std::memory_order_relaxed);
+    int32_t old __unused = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE, std::memory_order_relaxed);
     // A decStrong() must still happen after us.
     ALOG_ASSERT(old > INITIAL_STRONG_VALUE, "0x%x too small", old);
     refs->mBase->onFirstRef();
diff --git a/libutils/StopWatch.cpp b/libutils/StopWatch.cpp
index 219c13c..d01865e 100644
--- a/libutils/StopWatch.cpp
+++ b/libutils/StopWatch.cpp
@@ -30,10 +30,7 @@
 
 namespace android {
 
-
-StopWatch::StopWatch(const char *name, int clock, uint32_t flags)
-    :   mName(name), mClock(clock), mFlags(flags)
-{
+StopWatch::StopWatch(const char* name, int clock) : mName(name), mClock(clock) {
     reset();
 }
 
diff --git a/libutils/include/utils/StopWatch.h b/libutils/include/utils/StopWatch.h
index 693dd3c..76d78d0 100644
--- a/libutils/include/utils/StopWatch.h
+++ b/libutils/include/utils/StopWatch.h
@@ -29,21 +29,18 @@
 class StopWatch
 {
 public:
-        StopWatch(  const char *name,
-                    int clock = SYSTEM_TIME_MONOTONIC,
-                    uint32_t flags = 0);
-        ~StopWatch();
-        
-        const char* name() const;
-        nsecs_t     lap();
-        nsecs_t     elapsedTime() const;
+  StopWatch(const char* name, int clock = SYSTEM_TIME_MONOTONIC);
+  ~StopWatch();
 
-        void        reset();
-        
+  const char* name() const;
+  nsecs_t lap();
+  nsecs_t elapsedTime() const;
+
+  void reset();
+
 private:
     const char*     mName;
     int             mClock;
-    uint32_t        mFlags;
     
     struct lap_t {
         nsecs_t     soFar;
diff --git a/libutils/tests/Android.bp b/libutils/tests/Android.bp
index a891fca..a3e7ffe 100644
--- a/libutils/tests/Android.bp
+++ b/libutils/tests/Android.bp
@@ -77,6 +77,7 @@
     host_supported: true,
     relative_install_path: "libutils_tests",
     srcs: ["Singleton_test1.cpp"],
+    cflags: ["-Wall", "-Werror"],
 }
 
 cc_test_library {
@@ -84,5 +85,6 @@
     host_supported: true,
     relative_install_path: "libutils_tests",
     srcs: ["Singleton_test2.cpp"],
+    cflags: ["-Wall", "-Werror"],
     shared_libs: ["libutils_tests_singleton1"],
 }
diff --git a/libvndksupport/Android.bp b/libvndksupport/Android.bp
index b624223..fec79b7 100644
--- a/libvndksupport/Android.bp
+++ b/libvndksupport/Android.bp
@@ -3,6 +3,7 @@
 cc_library {
     name: "libvndksupport",
     srcs: ["linker.c"],
+    cflags: ["-Wall", "-Werror"],
     local_include_dirs: ["include/vndksupport"],
     export_include_dirs: ["include"],
     shared_libs: ["liblog"],
diff --git a/libvndksupport/tests/Android.bp b/libvndksupport/tests/Android.bp
index 3587cf8..5b467f8 100644
--- a/libvndksupport/tests/Android.bp
+++ b/libvndksupport/tests/Android.bp
@@ -17,6 +17,7 @@
     srcs: [
         "linker_test.cpp",
     ],
+    cflags: ["-Wall", "-Werror"],
 
     host_supported: false,
     shared_libs: [
diff --git a/libziparchive/include/ziparchive/zip_archive.h b/libziparchive/include/ziparchive/zip_archive.h
index dd463d1..018b1a9 100644
--- a/libziparchive/include/ziparchive/zip_archive.h
+++ b/libziparchive/include/ziparchive/zip_archive.h
@@ -265,6 +265,9 @@
  * Returns 0 on success and negative values on failure, for example if |reader|
  * cannot supply the right amount of data, or if the number of bytes written to
  * data does not match |uncompressed_length|.
+ *
+ * If |crc_out| is not nullptr, it is set to the crc32 checksum of the
+ * uncompressed data.
  */
 int32_t Inflate(const Reader& reader, const uint32_t compressed_length,
                 const uint32_t uncompressed_length, Writer* writer, uint64_t* crc_out);
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index a4b5dc5..35d0f0b 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -908,6 +908,7 @@
 
   std::unique_ptr<z_stream, decltype(zstream_deleter)> zstream_guard(&zstream, zstream_deleter);
 
+  const bool compute_crc = (crc_out != nullptr);
   uint64_t crc = 0;
   uint32_t remaining_bytes = compressed_length;
   do {
@@ -939,9 +940,8 @@
     if (zstream.avail_out == 0 || (zerr == Z_STREAM_END && zstream.avail_out != kBufSize)) {
       const size_t write_size = zstream.next_out - &write_buf[0];
       if (!writer->Append(&write_buf[0], write_size)) {
-        // The file might have declared a bogus length.
-        return kInconsistentInformation;
-      } else {
+        return kIoError;
+      } else if (compute_crc) {
         crc = crc32(crc, &write_buf[0], write_size);
       }
 
@@ -958,7 +958,9 @@
   // it ourselves above because there are no additional gains to be made by
   // having zlib calculate it for us, since they do it by calling crc32 in
   // the same manner that we have above.
-  *crc_out = crc;
+  if (compute_crc) {
+    *crc_out = crc;
+  }
 
   if (zstream.total_out != uncompressed_length || remaining_bytes != 0) {
     ALOGW("Zip: size mismatch on inflated file (%lu vs %" PRIu32 ")", zstream.total_out,
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index dbc14f0..cb72f0e 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -717,6 +717,93 @@
   ASSERT_STREQ("I/O error", ErrorCodeString(kIoError));
 }
 
+class VectorReader : public zip_archive::Reader {
+ public:
+  VectorReader(const std::vector<uint8_t>& input) : Reader(), input_(input) {}
+
+  bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const {
+    if ((offset + len) < input_.size()) {
+      return false;
+    }
+
+    memcpy(buf, &input_[offset], len);
+    return true;
+  }
+
+ private:
+  const std::vector<uint8_t>& input_;
+};
+
+class VectorWriter : public zip_archive::Writer {
+ public:
+  VectorWriter() : Writer() {}
+
+  bool Append(uint8_t* buf, size_t size) {
+    output_.insert(output_.end(), buf, buf + size);
+    return true;
+  }
+
+  std::vector<uint8_t>& GetOutput() { return output_; }
+
+ private:
+  std::vector<uint8_t> output_;
+};
+
+class BadReader : public zip_archive::Reader {
+ public:
+  BadReader() : Reader() {}
+
+  bool ReadAtOffset(uint8_t*, size_t, uint32_t) const { return false; }
+};
+
+class BadWriter : public zip_archive::Writer {
+ public:
+  BadWriter() : Writer() {}
+
+  bool Append(uint8_t*, size_t) { return false; }
+};
+
+TEST(ziparchive, Inflate) {
+  const uint32_t compressed_length = kATxtContentsCompressed.size();
+  const uint32_t uncompressed_length = kATxtContents.size();
+
+  const VectorReader reader(kATxtContentsCompressed);
+  {
+    VectorWriter writer;
+    uint64_t crc_out = 0;
+
+    int32_t ret =
+        zip_archive::Inflate(reader, compressed_length, uncompressed_length, &writer, &crc_out);
+    ASSERT_EQ(0, ret);
+    ASSERT_EQ(kATxtContents, writer.GetOutput());
+    ASSERT_EQ(0x950821C5u, crc_out);
+  }
+
+  {
+    VectorWriter writer;
+    int32_t ret =
+        zip_archive::Inflate(reader, compressed_length, uncompressed_length, &writer, nullptr);
+    ASSERT_EQ(0, ret);
+    ASSERT_EQ(kATxtContents, writer.GetOutput());
+  }
+
+  {
+    BadWriter writer;
+    int32_t ret =
+        zip_archive::Inflate(reader, compressed_length, uncompressed_length, &writer, nullptr);
+    ASSERT_EQ(kIoError, ret);
+  }
+
+  {
+    BadReader reader;
+    VectorWriter writer;
+    int32_t ret =
+        zip_archive::Inflate(reader, compressed_length, uncompressed_length, &writer, nullptr);
+    ASSERT_EQ(kIoError, ret);
+    ASSERT_EQ(0u, writer.GetOutput().size());
+  }
+}
+
 int main(int argc, char** argv) {
   ::testing::InitGoogleTest(&argc, argv);
 
diff --git a/trusty/keymaster/Android.bp b/trusty/keymaster/Android.bp
index 6b9d723..7735684 100644
--- a/trusty/keymaster/Android.bp
+++ b/trusty/keymaster/Android.bp
@@ -30,6 +30,7 @@
         "trusty_keymaster_ipc.cpp",
         "trusty_keymaster_main.cpp",
     ],
+    cflags: ["-Wall", "-Werror"],
     shared_libs: [
         "libcrypto",
         "libcutils",
diff --git a/trusty/keymaster/trusty_keymaster_main.cpp b/trusty/keymaster/trusty_keymaster_main.cpp
index 9c2ae2d..ed78b7f 100644
--- a/trusty/keymaster/trusty_keymaster_main.cpp
+++ b/trusty/keymaster/trusty_keymaster_main.cpp
@@ -289,7 +289,6 @@
     std::unique_ptr<const uint8_t[]> deleter(key.key_material);
 
     printf("=== Signing with imported ECDSA key ===\n");
-    keymaster_ec_sign_params_t sign_params = {DIGEST_NONE};
     size_t message_len = 30 /* arbitrary */;
     std::unique_ptr<uint8_t[]> message(new uint8_t[message_len]);
     memset(message.get(), 'a', message_len);
diff --git a/trusty/libtrusty/Android.bp b/trusty/libtrusty/Android.bp
index f316da2..1a8db2f 100644
--- a/trusty/libtrusty/Android.bp
+++ b/trusty/libtrusty/Android.bp
@@ -21,6 +21,7 @@
 
     srcs: ["trusty.c"],
     export_include_dirs: ["include"],
+    cflags: ["-Wall", "-Werror"],
 
     shared_libs: ["liblog"],
 }
diff --git a/trusty/libtrusty/tipc-test/Android.bp b/trusty/libtrusty/tipc-test/Android.bp
index cb00fe7..6ec8c23 100644
--- a/trusty/libtrusty/tipc-test/Android.bp
+++ b/trusty/libtrusty/tipc-test/Android.bp
@@ -23,4 +23,5 @@
         "liblog",
     ],
     gtest: false,
+    cflags: ["-Wall", "-Werror"],
 }