Update to v5.6 kernel headers.

Kernel headers coming from:

Git: https://android.googlesource.com/kernel/common/
Branch: android-mainline
Tag: android-mainline-5.6

Add a new method for removing structures. This is to deal with the kernel
headers changing some definitions of timeval to __kernel_old_timeval
and itimerval to __kernel_old_itimerval. Remove the __kernel_old_XX
strutures and change the other structures to the previous definitions.

This only works so long as these structures stay the same, if they
diverge, then a different strategy will need to be implemented.

Test: Booted cuttlefish/walleye.
Test: Ran bionic-unit-tests on cuttlefish/walleye.
Change-Id: I0a61f4fa6e4155c602e0414d9b38c2e1637829af
diff --git a/libc/kernel/tools/clean_header.py b/libc/kernel/tools/clean_header.py
index 92a2139..2c2d001 100755
--- a/libc/kernel/tools/clean_header.py
+++ b/libc/kernel/tools/clean_header.py
@@ -112,6 +112,7 @@
     if arch and arch in kernel_arch_token_replacements:
         blocks.replaceTokens(kernel_arch_token_replacements[arch])
 
+    blocks.removeStructs(kernel_structs_to_remove)
     blocks.optimizeMacros(macros)
     blocks.optimizeIf01()
     blocks.removeVarsAndFuncs(kernel_known_generic_statics)
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index 1ada59e..b6a1538 100755
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -30,10 +30,7 @@
 # Note that setting LD_LIBRARY_PATH with os.putenv() sometimes doesn't help.
 clang.cindex.Config.set_library_file(os.path.join(top, 'prebuilts/sdk/tools/linux/lib64/libclang_android.so'))
 
-from defaults import kCppUndefinedMacro
-from defaults import kernel_remove_config_macros
-from defaults import kernel_struct_replacements
-from defaults import kernel_token_replacements
+from defaults import *
 
 
 debugBlockParser = False
@@ -1198,6 +1195,52 @@
             if b.isIf():
                 b.expr.optimize(macros)
 
+    def removeStructs(self, structs):
+        """Remove structs."""
+        for b in self.blocks:
+            # Have to look in each block for a top-level struct definition.
+            if b.directive:
+                continue
+            num_tokens = len(b.tokens)
+            # A struct definition has at least 5 tokens:
+            #   struct
+            #   ident
+            #   {
+            #   }
+            #   ;
+            if num_tokens < 5:
+                continue
+            # This is a simple struct finder, it might fail if a top-level
+            # structure has an #if type directives that confuses the algorithm
+            # for finding th end of the structure. Or if there is another
+            # structure definition embedded in the structure.
+            i = 0
+            while i < num_tokens - 2:
+                if (b.tokens[i].kind != TokenKind.KEYWORD or
+                    b.tokens[i].id != "struct"):
+                    i += 1
+                    continue
+                if (b.tokens[i + 1].kind == TokenKind.IDENTIFIER and
+                    b.tokens[i + 2].kind == TokenKind.PUNCTUATION and
+                    b.tokens[i + 2].id == "{" and b.tokens[i + 1].id in structs):
+                    # Search forward for the end of the structure.
+                    # Very simple search, look for } and ; tokens. If something
+                    # more complicated is needed we can add it later.
+                    j = i + 3
+                    while j < num_tokens - 1:
+                        if (b.tokens[j].kind == TokenKind.PUNCTUATION and
+                            b.tokens[j].id == "}" and
+                            b.tokens[j + 1].kind == TokenKind.PUNCTUATION and
+                            b.tokens[j + 1].id == ";"):
+                            b.tokens = b.tokens[0:i] + b.tokens[j + 2:num_tokens]
+                            num_tokens = len(b.tokens)
+                            j = i
+                            break
+                        j += 1
+                    i = j
+                    continue
+                i += 1
+
     def optimizeAll(self, macros):
         self.optimizeMacros(macros)
         self.optimizeIf01()
@@ -1755,7 +1798,6 @@
     def parse(self, text, macros=None):
         out = utils.StringOutput()
         blocks = BlockParser().parse(CppStringTokenizer(text))
-        blocks.replaceTokens(kernel_token_replacements)
         blocks.optimizeAll(macros)
         blocks.write(out)
         return out.get()
@@ -1931,8 +1973,8 @@
 #endif /* SIGRTMAX */
 """
         expected = """\
-#ifndef __SIGRTMAX
-#define __SIGRTMAX 123
+#ifndef SIGRTMAX
+#define SIGRTMAX 123
 #endif
 """
         self.assertEqual(self.parse(text), expected)
@@ -1948,6 +1990,146 @@
         expected = ""
         self.assertEqual(self.parse(text), expected)
 
+class RemoveStructsTests(unittest.TestCase):
+    def parse(self, text, structs):
+        out = utils.StringOutput()
+        blocks = BlockParser().parse(CppStringTokenizer(text))
+        blocks.removeStructs(structs)
+        blocks.write(out)
+        return out.get()
+
+    def test_remove_struct_from_start(self):
+        text = """\
+struct remove {
+  int val1;
+  int val2;
+};
+struct something {
+  struct timeval val1;
+  struct timeval val2;
+};
+"""
+        expected = """\
+struct something {
+  struct timeval val1;
+  struct timeval val2;
+};
+"""
+        self.assertEqual(self.parse(text, set(["remove"])), expected)
+
+    def test_remove_struct_from_end(self):
+        text = """\
+struct something {
+  struct timeval val1;
+  struct timeval val2;
+};
+struct remove {
+  int val1;
+  int val2;
+};
+"""
+        expected = """\
+struct something {
+  struct timeval val1;
+  struct timeval val2;
+};
+"""
+        self.assertEqual(self.parse(text, set(["remove"])), expected)
+
+    def test_remove_minimal_struct(self):
+        text = """\
+struct remove {
+};
+"""
+        expected = "";
+        self.assertEqual(self.parse(text, set(["remove"])), expected)
+
+    def test_remove_struct_with_struct_fields(self):
+        text = """\
+struct something {
+  struct remove val1;
+  struct remove val2;
+};
+struct remove {
+  int val1;
+  struct something val3;
+  int val2;
+};
+"""
+        expected = """\
+struct something {
+  struct remove val1;
+  struct remove val2;
+};
+"""
+        self.assertEqual(self.parse(text, set(["remove"])), expected)
+
+    def test_remove_consecutive_structs(self):
+        text = """\
+struct keep1 {
+  struct timeval val1;
+  struct timeval val2;
+};
+struct remove1 {
+  int val1;
+  int val2;
+};
+struct remove2 {
+  int val1;
+  int val2;
+  int val3;
+};
+struct keep2 {
+  struct timeval val1;
+  struct timeval val2;
+};
+"""
+        expected = """\
+struct keep1 {
+  struct timeval val1;
+  struct timeval val2;
+};
+struct keep2 {
+  struct timeval val1;
+  struct timeval val2;
+};
+"""
+        self.assertEqual(self.parse(text, set(["remove1", "remove2"])), expected)
+
+    def test_remove_multiple_structs(self):
+        text = """\
+struct keep1 {
+  int val;
+};
+struct remove1 {
+  int val1;
+  int val2;
+};
+struct keep2 {
+  int val;
+};
+struct remove2 {
+  struct timeval val1;
+  struct timeval val2;
+};
+struct keep3 {
+  int val;
+};
+"""
+        expected = """\
+struct keep1 {
+  int val;
+};
+struct keep2 {
+  int val;
+};
+struct keep3 {
+  int val;
+};
+"""
+        self.assertEqual(self.parse(text, set(["remove1", "remove2"])), expected)
+
+
 class FullPathTest(unittest.TestCase):
     """Test of the full path parsing."""
 
@@ -1956,9 +2138,12 @@
             keep = set()
         out = utils.StringOutput()
         blocks = BlockParser().parse(CppStringTokenizer(text))
+
+        blocks.removeStructs(kernel_structs_to_remove)
         blocks.removeVarsAndFuncs(keep)
         blocks.replaceTokens(kernel_token_replacements)
         blocks.optimizeAll(None)
+
         blocks.write(out)
         return out.get()
 
@@ -2241,6 +2426,38 @@
 """
         self.assertEqual(self.parse(text), expected)
 
+    def test_verify_timeval_itemerval(self):
+        text = """\
+struct __kernel_old_timeval {
+  struct something val;
+};
+struct __kernel_old_itimerval {
+  struct __kernel_old_timeval val;
+};
+struct fields {
+  struct __kernel_old_timeval timeval;
+  struct __kernel_old_itimerval itimerval;
+};
+"""
+        expected = """\
+struct fields {
+  struct timeval timeval;
+  struct itimerval itimerval;
+};
+"""
+        self.assertEqual(self.parse(text), expected)
+
+    def test_token_replacement(self):
+        text = """\
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+"""
+        expected = """\
+#define __SIGRTMIN 32
+#define __SIGRTMAX _KERNEL__NSIG
+"""
+        self.assertEqual(self.parse(text), expected)
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 90b56f5..04eb5f1 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -35,6 +35,17 @@
     "__kernel_old_timeval": "1",
     }
 
+# this is the set of known kernel data structures we want to remove from
+# the final headers
+kernel_structs_to_remove = set(
+        [
+          # Remove the structures since they are still the same as
+          # timeval, itimerval.
+          "__kernel_old_timeval",
+          "__kernel_old_itimerval",
+        ]
+    )
+
 # define to true if you want to remove all defined(CONFIG_FOO) tests
 # from the clean headers. testing shows that this is not strictly necessary
 # but just generates cleaner results
@@ -86,6 +97,8 @@
     # If struct __kernel_old_timeval and struct timeval become different,
     # then a different solution needs to be implemented.
     "__kernel_old_timeval": "timeval",
+    # Do the same for __kernel_old_itimerval as for timeval.
+    "__kernel_old_itimerval": "itimerval",
     }