Merge "fastboot: handle small flash block sizes correctly"
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/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..46a6f76 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,34 @@
   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, non_virtual_thunk) {
+  Demangler demangler;
+
+  ASSERT_EQ("non-virtual thunk to one", demangler.Parse("_ZThn0_N3oneE"));
+  ASSERT_EQ("non-virtual thunk to two", demangler.Parse("_ZThn0_3two"));
+  ASSERT_EQ("non-virtual thunk to three", demangler.Parse("_ZTh0_5three"));
+  ASSERT_EQ("non-virtual thunk to four", demangler.Parse("_ZTh_4four"));
+  ASSERT_EQ("non-virtual thunk to five", demangler.Parse("_ZTh0123456789_4five"));
+  ASSERT_EQ("non-virtual thunk to six", demangler.Parse("_ZThn0123456789_3six"));
+
+  ASSERT_EQ("_ZThn0N3oneE", demangler.Parse("_ZThn0N3oneE"));
+  ASSERT_EQ("_ZThn03two", demangler.Parse("_ZThn03two"));
+  ASSERT_EQ("_ZTh05three", demangler.Parse("_ZTh05three"));
+  ASSERT_EQ("_ZTh4four", demangler.Parse("_ZTh4four"));
+  ASSERT_EQ("_ZTh01234567894five", demangler.Parse("_ZTh01234567894five"));
+  ASSERT_EQ("_ZThn01234567893six", demangler.Parse("_ZThn01234567893six"));
+  ASSERT_EQ("_ZT_N3oneE", demangler.Parse("_ZT_N3oneE"));
+  ASSERT_EQ("_ZT0_N3oneE", demangler.Parse("_ZT0_N3oneE"));
+  ASSERT_EQ("_ZTH_N3oneE", demangler.Parse("_ZTH_N3oneE"));
 }
 
 TEST(DemangleTest, demangle) {
diff --git a/demangle/Demangler.cpp b/demangle/Demangler.cpp
index f148b21..af2816c 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()) {
@@ -361,7 +388,7 @@
       saves_.pop_back();
     }
 
-    function_name_ = cur_state_.str;
+    function_name_ += cur_state_.str;
     while (!cur_state_.suffixes.empty()) {
       function_suffix_ += cur_state_.suffixes.back();
       cur_state_.suffixes.pop_back();
@@ -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,57 @@
     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 == 'T') {
+    // non-virtual thunk, verify that it matches one of these patterns:
+    //   Thn[0-9]+_
+    //   Th[0-9]+_
+    //   Thn_
+    //   Th_
+    name++;
+    if (*name != 'h') {
+      return nullptr;
+    }
+    name++;
+    if (*name == 'n') {
+      name++;
+    }
+    while (std::isdigit(*name)) {
+      name++;
+    }
+    if (*name != '_') {
+      return nullptr;
+    }
+    function_name_ = "non-virtual thunk to ";
+    return name + 1;
+  }
+
   if (*name == 'N') {
-    parse_funcs_.push_back(&Demangler::ParseArguments);
+    parse_funcs_.push_back(&Demangler::ParseArgumentsAtTopLevel);
     parse_func_ = &Demangler::ParseFunctionName;
     return name + 1;
   }
@@ -732,11 +824,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 +873,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 +898,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/fastboot/Android.mk b/fastboot/Android.mk
index dd8bad9..bc88002 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -58,7 +58,6 @@
 
 LOCAL_STATIC_LIBRARIES := \
     libziparchive \
-    libext4_utils \
     libsparse \
     libutils \
     liblog \
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 222d64f..40c18e0 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1354,7 +1354,7 @@
 
 static unsigned fb_get_flash_block_size(Transport* transport, std::string name) {
     std::string sizeString;
-    if (!fb_getvar(transport, name.c_str(), &sizeString)) {
+    if (!fb_getvar(transport, name.c_str(), &sizeString) || sizeString.empty()) {
         /* This device does not report flash block sizes, so return 0 */
         return 0;
     }
diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp
index e78e97f..2d77dd6 100644
--- a/fastboot/fs.cpp
+++ b/fastboot/fs.cpp
@@ -23,7 +23,6 @@
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
 #include <android-base/unique_fd.h>
-#include <ext4_utils/make_ext4fs.h>
 #include <sparse/sparse.h>
 
 using android::base::StringPrintf;
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/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 92c6ee8..2c18a6d 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -700,25 +700,44 @@
 }
 
 /*
- * tries to load default fstab.<hardware> file from /odm/etc, /vendor/etc
- * or /. loads the first one found and also combines fstab entries passed
- * in from device tree.
+ * Identify path to fstab file. Lookup is based on pattern
+ * fstab.<hardware>, fstab.<hardware.platform> in folders
+   /odm/etc, vendor/etc, or /.
+ */
+static std::string get_fstab_path()
+{
+    for (const char* prop : {"hardware", "hardware.platform"}) {
+        std::string hw;
+
+        if (!fs_mgr_get_boot_config(prop, &hw)) continue;
+
+        for (const char* prefix : {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab."}) {
+            std::string fstab_path = prefix + hw;
+            if (access(fstab_path.c_str(), F_OK) == 0) {
+                return fstab_path;
+            }
+        }
+    }
+
+    return std::string();
+}
+
+/*
+ * loads the fstab file and combines with fstab entries passed in from device tree.
  */
 struct fstab *fs_mgr_read_fstab_default()
 {
-    std::string hw;
     std::string default_fstab;
 
     // Use different fstab paths for normal boot and recovery boot, respectively
     if (access("/sbin/recovery", F_OK) == 0) {
         default_fstab = "/etc/recovery.fstab";
-    } else if (fs_mgr_get_boot_config("hardware", &hw)) {  // normal boot
-        for (const char *prefix : {"/odm/etc/fstab.","/vendor/etc/fstab.", "/fstab."}) {
-            default_fstab = prefix + hw;
-            if (access(default_fstab.c_str(), F_OK) == 0) break;
-        }
-    } else {
-        LWARNING << __FUNCTION__ << "(): failed to find device hardware name";
+    } else {  // normal boot
+        default_fstab = get_fstab_path();
+    }
+
+    if (default_fstab.empty()) {
+        LWARNING << __FUNCTION__ << "(): failed to find device default fstab";
     }
 
     // combines fstab entries passed in from device tree with
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/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index d17c211..3a38839 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -44,13 +44,13 @@
 #include "UnwindStackMap.h"
 
 bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
-                       std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames) {
-  std::vector<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"};
+                       std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames,
+                       std::vector<std::string>* skip_names) {
   UnwindStackMap* stack_map = reinterpret_cast<UnwindStackMap*>(back_map);
   auto process_memory = stack_map->process_memory();
   unwindstack::Unwinder unwinder(MAX_BACKTRACE_FRAMES + num_ignore_frames, stack_map->stack_maps(),
                                  regs, stack_map->process_memory());
-  unwinder.Unwind(&skip_names, &stack_map->GetSuffixesToIgnore());
+  unwinder.Unwind(skip_names, &stack_map->GetSuffixesToIgnore());
 
   if (num_ignore_frames >= unwinder.NumFrames()) {
     frames->resize(0);
@@ -104,7 +104,8 @@
   }
 
   error_ = BACKTRACE_UNWIND_NO_ERROR;
-  return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames);
+  std::vector<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"};
+  return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames, &skip_names);
 }
 
 UnwindStackPtrace::UnwindStackPtrace(pid_t pid, pid_t tid, BacktraceMap* map)
@@ -124,5 +125,5 @@
   }
 
   error_ = BACKTRACE_UNWIND_NO_ERROR;
-  return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames);
+  return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames, nullptr);
 }
diff --git a/libbacktrace/include/backtrace/Backtrace.h b/libbacktrace/include/backtrace/Backtrace.h
index 73a58b5..e073533 100644
--- a/libbacktrace/include/backtrace/Backtrace.h
+++ b/libbacktrace/include/backtrace/Backtrace.h
@@ -109,7 +109,8 @@
   virtual bool Unwind(size_t num_ignore_frames, ucontext_t* context = NULL) = 0;
 
   static bool Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
-                     std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames);
+                     std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames,
+                     std::vector<std::string>* skip_names);
 
   // Get the function name and offset into the function given the pc.
   // If the string is empty, then no valid function name was found,
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/libpixelflinger/Android.mk b/libpixelflinger/Android.mk
index 55891db..c7306cd 100644
--- a/libpixelflinger/Android.mk
+++ b/libpixelflinger/Android.mk
@@ -25,6 +25,8 @@
 	buffer.cpp
 
 PIXELFLINGER_CFLAGS := -fstrict-aliasing -fomit-frame-pointer
+PIXELFLINGER_CFLAGS += -Wall -Werror
+PIXELFLINGER_CFLAGS += -Wno-unused-function
 
 PIXELFLINGER_SRC_FILES_arm := \
 	codeflinger/ARMAssembler.cpp \
diff --git a/libpixelflinger/codeflinger/Arm64Assembler.cpp b/libpixelflinger/codeflinger/Arm64Assembler.cpp
index bff87bb..aebc129 100644
--- a/libpixelflinger/codeflinger/Arm64Assembler.cpp
+++ b/libpixelflinger/codeflinger/Arm64Assembler.cpp
@@ -151,11 +151,11 @@
 
 namespace android {
 
-static const char* shift_codes[] =
+static __unused const char* shift_codes[] =
 {
     "LSL", "LSR", "ASR", "ROR"
 };
-static const char *cc_codes[] =
+static __unused const char *cc_codes[] =
 {
     "EQ", "NE", "CS", "CC", "MI",
     "PL", "VS", "VC", "HI", "LS",
@@ -984,7 +984,7 @@
 // A64 instructions
 // ----------------------------------------------------------------------------
 
-static const char * dataTransferOpName[] =
+static __unused const char * dataTransferOpName[] =
 {
     "LDR","LDRB","LDRH","STR","STRB","STRH"
 };
diff --git a/libpixelflinger/codeflinger/GGLAssembler.cpp b/libpixelflinger/codeflinger/GGLAssembler.cpp
index 91fbd53..04e285d 100644
--- a/libpixelflinger/codeflinger/GGLAssembler.cpp
+++ b/libpixelflinger/codeflinger/GGLAssembler.cpp
@@ -94,8 +94,6 @@
 
 int GGLAssembler::scanline_core(const needs_t& needs, context_t const* c)
 {
-    int64_t duration = ggl_system_time();
-
     mBlendFactorCached = 0;
     mBlending = 0;
     mMasking = 0;
@@ -353,7 +351,6 @@
     fragment_parts_t& parts, const needs_t& needs)
 {
     Scratch scratches(registerFile());
-    int Rctx = mBuilderContext.Rctx;
 
     // compute count
     comment("compute ct (# of pixels to process)");
diff --git a/libpixelflinger/codeflinger/load_store.cpp b/libpixelflinger/codeflinger/load_store.cpp
index da21e1d..4db0a49 100644
--- a/libpixelflinger/codeflinger/load_store.cpp
+++ b/libpixelflinger/codeflinger/load_store.cpp
@@ -232,7 +232,6 @@
 void GGLAssembler::downshift(
         pixel_t& d, int component, component_t s, const reg_t& dither)
 {
-    const needs_t& needs = mBuilderContext.needs;
     Scratch scratches(registerFile());
 
     int sh = s.h;
diff --git a/libpixelflinger/codeflinger/texturing.cpp b/libpixelflinger/codeflinger/texturing.cpp
index 4c357af..e6997bd 100644
--- a/libpixelflinger/codeflinger/texturing.cpp
+++ b/libpixelflinger/codeflinger/texturing.cpp
@@ -41,7 +41,6 @@
 void GGLAssembler::init_iterated_color(fragment_parts_t& parts, const reg_t& x)
 {
     context_t const* c = mBuilderContext.c;
-    const needs_t& needs = mBuilderContext.needs;
 
     if (mSmooth) {
         // NOTE: we could take this case in the mDithering + !mSmooth case,
@@ -324,9 +323,7 @@
         tex_coord_t* coords,
         const reg_t& x, const reg_t& y)
 {
-    context_t const* c = mBuilderContext.c;
     const needs_t& needs = mBuilderContext.needs;
-    int Rctx = mBuilderContext.Rctx;
     int Rx = x.reg;
     int Ry = y.reg;
 
@@ -402,10 +399,6 @@
 void GGLAssembler::build_textures(  fragment_parts_t& parts,
                                     Scratch& regs)
 {
-    context_t const* c = mBuilderContext.c;
-    const needs_t& needs = mBuilderContext.needs;
-    int Rctx = mBuilderContext.Rctx;
-
     // We don't have a way to spill registers automatically
     // spill depth and AA regs, when we know we may have to.
     // build the spill list...
@@ -434,7 +427,6 @@
 
     Spill spill(registerFile(), *this, spill_list);
 
-    const bool multiTexture = mTextureMachine.activeUnits > 1;
     for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT; i++) {
         const texture_unit_t& tmu = mTextureMachine.tmu[i];
         if (tmu.format_idx == 0)
@@ -442,7 +434,7 @@
 
         pointer_t& txPtr = parts.coords[i].ptr;
         pixel_t& texel = parts.texel[i];
-            
+
         // repeat...
         if ((tmu.swrap == GGL_NEEDS_WRAP_11) &&
             (tmu.twrap == GGL_NEEDS_WRAP_11))
@@ -656,7 +648,6 @@
 void GGLAssembler::build_iterate_texture_coordinates(
     const fragment_parts_t& parts)
 {
-    const bool multiTexture = mTextureMachine.activeUnits > 1;
     for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT; i++) {
         const texture_unit_t& tmu = mTextureMachine.tmu[i];
         if (tmu.format_idx == 0)
diff --git a/libpixelflinger/include/private/pixelflinger/ggl_fixed.h b/libpixelflinger/include/private/pixelflinger/ggl_fixed.h
index 17b85dd..51e9e26 100644
--- a/libpixelflinger/include/private/pixelflinger/ggl_fixed.h
+++ b/libpixelflinger/include/private/pixelflinger/ggl_fixed.h
@@ -497,7 +497,6 @@
 {
 
     GGLfixed result;
-    int rshift;
 
     asm("smull  %x[result], %w[x], %w[y]                     \n"
         "lsr    %x[result], %x[result], %x[shift]            \n"
diff --git a/libpixelflinger/raster.cpp b/libpixelflinger/raster.cpp
index 26d8e45..e95c2c8 100644
--- a/libpixelflinger/raster.cpp
+++ b/libpixelflinger/raster.cpp
@@ -153,7 +153,6 @@
      GGLint h = where[3];
 
     // exclsively enable this tmu
-    const GGLSurface& cbSurface = c->state.buffers.color.s;
     c->procs.activeTexture(c, tmu);
     c->procs.disable(c, GGL_W_LERP);
 
diff --git a/libpixelflinger/scanline.cpp b/libpixelflinger/scanline.cpp
index c6cf5bf..4cc23c7 100644
--- a/libpixelflinger/scanline.cpp
+++ b/libpixelflinger/scanline.cpp
@@ -2144,7 +2144,6 @@
     const int32_t u = (c->state.texture[0].shade.is0>>16) + x;
     const int32_t v = (c->state.texture[0].shade.it0>>16) + y;
     uint32_t *src = reinterpret_cast<uint32_t*>(tex->data)+(u+(tex->stride*v));
-    int sR, sG, sB;
     uint32_t s, d;
 
     if (ct==1 || uintptr_t(dst)&2) {
diff --git a/libpixelflinger/tests/arch-arm64/assembler/Android.mk b/libpixelflinger/tests/arch-arm64/assembler/Android.mk
index bd0f24b..db5dc4d 100644
--- a/libpixelflinger/tests/arch-arm64/assembler/Android.mk
+++ b/libpixelflinger/tests/arch-arm64/assembler/Android.mk
@@ -14,6 +14,8 @@
 
 LOCAL_MODULE:= test-pixelflinger-arm64-assembler-test
 
+LOCAL_CFLAGS := -Wall -Werror
+
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_MULTILIB := 64
diff --git a/libpixelflinger/tests/arch-arm64/col32cb16blend/Android.mk b/libpixelflinger/tests/arch-arm64/col32cb16blend/Android.mk
index 3368eb0..3096232 100644
--- a/libpixelflinger/tests/arch-arm64/col32cb16blend/Android.mk
+++ b/libpixelflinger/tests/arch-arm64/col32cb16blend/Android.mk
@@ -11,6 +11,8 @@
 
 LOCAL_MODULE:= test-pixelflinger-arm64-col32cb16blend
 
+LOCAL_CFLAGS := -Wall -Werror
+
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_MULTILIB := 64
diff --git a/libpixelflinger/tests/arch-arm64/disassembler/Android.mk b/libpixelflinger/tests/arch-arm64/disassembler/Android.mk
index d8f7e69..78f12af 100644
--- a/libpixelflinger/tests/arch-arm64/disassembler/Android.mk
+++ b/libpixelflinger/tests/arch-arm64/disassembler/Android.mk
@@ -9,6 +9,8 @@
 
 LOCAL_MODULE:= test-pixelflinger-arm64-disassembler-test
 
+LOCAL_CFLAGS := -Wall -Werror
+
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_MULTILIB := 64
diff --git a/libpixelflinger/tests/arch-arm64/t32cb16blend/Android.mk b/libpixelflinger/tests/arch-arm64/t32cb16blend/Android.mk
index 8e5ec5e..664347f 100644
--- a/libpixelflinger/tests/arch-arm64/t32cb16blend/Android.mk
+++ b/libpixelflinger/tests/arch-arm64/t32cb16blend/Android.mk
@@ -11,6 +11,8 @@
 
 LOCAL_MODULE:= test-pixelflinger-arm64-t32cb16blend
 
+LOCAL_CFLAGS := -Wall -Werror
+
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_MULTILIB := 64
diff --git a/libpixelflinger/tests/codegen/Android.mk b/libpixelflinger/tests/codegen/Android.mk
index 2f9ca2f..72d71ef 100644
--- a/libpixelflinger/tests/codegen/Android.mk
+++ b/libpixelflinger/tests/codegen/Android.mk
@@ -13,6 +13,8 @@
 
 LOCAL_MODULE:= test-opengl-codegen
 
+LOCAL_CFLAGS:= -Wall -Werror
+
 LOCAL_MODULE_TAGS := tests
 
 include $(BUILD_NATIVE_TEST)
diff --git a/libpixelflinger/tests/codegen/codegen.cpp b/libpixelflinger/tests/codegen/codegen.cpp
index efa6d87..dce4ed7 100644
--- a/libpixelflinger/tests/codegen/codegen.cpp
+++ b/libpixelflinger/tests/codegen/codegen.cpp
@@ -40,9 +40,9 @@
     const AssemblyKey<needs_t>& key() const { return mKey; }
 };
 
+#if ANDROID_ARM_CODEGEN
 static void ggl_test_codegen(uint32_t n, uint32_t p, uint32_t t0, uint32_t t1)
 {
-#if ANDROID_ARM_CODEGEN
     GGLContext* c;
     gglInit(&c);
     needs_t needs;
@@ -73,10 +73,12 @@
         printf("error %08x (%s)\n", err, strerror(-err));
     }
     gglUninit(c);
-#else
-    printf("This test runs only on ARM, Arm64 or MIPS\n");
-#endif
 }
+#else
+static void ggl_test_codegen(uint32_t, uint32_t, uint32_t, uint32_t) {
+    printf("This test runs only on ARM, Arm64 or MIPS\n");
+}
+#endif
 
 int main(int argc, char** argv)
 {
diff --git a/libpixelflinger/tests/gglmul/Android.mk b/libpixelflinger/tests/gglmul/Android.mk
index 75bd39e..67f358f 100644
--- a/libpixelflinger/tests/gglmul/Android.mk
+++ b/libpixelflinger/tests/gglmul/Android.mk
@@ -11,6 +11,8 @@
 
 LOCAL_MODULE:= test-pixelflinger-gglmul
 
+LOCAL_CFLAGS:= -Wall -Werror
+
 LOCAL_MODULE_TAGS := tests
 
 include $(BUILD_NATIVE_TEST)
diff --git a/libpixelflinger/trap.cpp b/libpixelflinger/trap.cpp
index 234bfdd..06ad237 100644
--- a/libpixelflinger/trap.cpp
+++ b/libpixelflinger/trap.cpp
@@ -349,7 +349,6 @@
 
 static void linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord width)
 {
-    GGL_CONTEXT(c, con);
     GGLcoord v[4][2];
     v[0][0] = v0[0];    v[0][1] = v0[1];
     v[1][0] = v1[0];    v[1][1] = v1[1];
@@ -377,7 +376,6 @@
 
 static void aa_linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord width)
 {
-    GGL_CONTEXT(c, con);
     GGLcoord v[4][2];
     v[0][0] = v0[0];    v[0][1] = v0[1];
     v[1][0] = v1[0];    v[1][1] = v1[1];
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/toolbox/Android.mk b/toolbox/Android.mk
index 94029d8..c4795a7 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -59,3 +59,12 @@
 $(INPUT_H_LABELS_H): $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/generate-input.h-labels.py $(UAPI_INPUT_EVENT_CODES_H)
 $(INPUT_H_LABELS_H):
 	$(transform-generated-source)
+
+# We only want 'r' on userdebug and eng builds.
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := r.c
+LOCAL_CFLAGS += $(common_cflags)
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/upstream-netbsd/include/
+LOCAL_MODULE := r
+LOCAL_MODULE_TAGS := debug
+include $(BUILD_EXECUTABLE)
diff --git a/toolbox/r.c b/toolbox/r.c
new file mode 100644
index 0000000..b96cdb2
--- /dev/null
+++ b/toolbox/r.c
@@ -0,0 +1,102 @@
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#if __LP64__
+#define strtoptr strtoull
+#else
+#define strtoptr strtoul
+#endif
+
+static int usage()
+{
+    fprintf(stderr,"r [-b|-s] <address> [<value>]\n");
+    return -1;
+}
+
+int main(int argc, char *argv[])
+{
+    if(argc < 2) return usage();
+
+    int width = 4;
+    if(!strcmp(argv[1], "-b")) {
+        width = 1;
+        argc--;
+        argv++;
+    } else if(!strcmp(argv[1], "-s")) {
+        width = 2;
+        argc--;
+        argv++;
+    }
+
+    if(argc < 2) return usage();
+    uintptr_t addr = strtoptr(argv[1], 0, 16);
+
+    uintptr_t endaddr = 0;
+    char* end = strchr(argv[1], '-');
+    if (end)
+        endaddr = strtoptr(end + 1, 0, 16);
+
+    if (!endaddr)
+        endaddr = addr + width - 1;
+
+    if (endaddr <= addr) {
+        fprintf(stderr, "end address <= start address\n");
+        return -1;
+    }
+
+    bool set = false;
+    uint32_t value = 0;
+    if(argc > 2) {
+        set = true;
+        value = strtoul(argv[2], 0, 16);
+    }
+
+    int fd = open("/dev/mem", O_RDWR | O_SYNC);
+    if(fd < 0) {
+        fprintf(stderr,"cannot open /dev/mem\n");
+        return -1;
+    }
+
+    off64_t mmap_start = addr & ~(PAGE_SIZE - 1);
+    size_t mmap_size = endaddr - mmap_start + 1;
+    mmap_size = (mmap_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+
+    void* page = mmap64(0, mmap_size, PROT_READ | PROT_WRITE,
+                        MAP_SHARED, fd, mmap_start);
+
+    if(page == MAP_FAILED){
+        fprintf(stderr,"cannot mmap region\n");
+        return -1;
+    }
+
+    while (addr <= endaddr) {
+        switch(width){
+        case 4: {
+            uint32_t* x = (uint32_t*) (((uintptr_t) page) + (addr & 4095));
+            if(set) *x = value;
+            fprintf(stderr,"%08"PRIxPTR": %08x\n", addr, *x);
+            break;
+        }
+        case 2: {
+            uint16_t* x = (uint16_t*) (((uintptr_t) page) + (addr & 4095));
+            if(set) *x = value;
+            fprintf(stderr,"%08"PRIxPTR": %04x\n", addr, *x);
+            break;
+        }
+        case 1: {
+            uint8_t* x = (uint8_t*) (((uintptr_t) page) + (addr & 4095));
+            if(set) *x = value;
+            fprintf(stderr,"%08"PRIxPTR": %02x\n", addr, *x);
+            break;
+        }
+        }
+        addr += width;
+    }
+    return 0;
+}
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"],
 }