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/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()