Use in_addr in ip_mreq_source and ip_msfilter.

This adds a new mechanism to say "replace struct S with #include <bits/S.h>".

Also switch epoll_event over to the new mechanism.

Also use the kernel's struct sockaddr_storage directly rather than behind
an unnecessary #define.

This patch also removes some dead code in the header scrubber. This code
still needs rewriting completely. I learned that a "block" isn't necessarily
a single struct definition, say; it might be a run of them. It seems like
a block is a run of preprocessor directives or a run of regular code.

Bug: https://issuetracker.google.com/36987220
Test: new test
Change-Id: Ic6a5c09559766a4babe3cd4c3ea538b885e07308
diff --git a/libc/kernel/tools/clean_header.py b/libc/kernel/tools/clean_header.py
index d63ea03..7c802c2 100755
--- a/libc/kernel/tools/clean_header.py
+++ b/libc/kernel/tools/clean_header.py
@@ -94,11 +94,9 @@
 
     # Extract the architecture if found.
     arch = None
-    statics = kernel_known_generic_statics
     m = re.search(r"(^|/)asm-([\w\d_\+\.\-]+)/.*", rel_path)
     if m and m.group(2) != 'generic':
         arch = m.group(2)
-        statics = statics.union(kernel_known_statics.get(arch, set()))
 
     # Now, let's parse the file.
     parser = cpp.BlockParser()
@@ -116,9 +114,8 @@
 
     blocks.optimizeMacros(macros)
     blocks.optimizeIf01()
-    blocks.removeVarsAndFuncs(statics)
+    blocks.removeVarsAndFuncs(kernel_known_generic_statics)
     blocks.replaceTokens(kernel_token_replacements)
-    blocks.removeMacroDefines(kernel_ignored_macros)
 
     out = StringOutput()
     out.write(kernel_disclaimer)
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index 68144cd..2400f5d 100644
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -31,6 +31,7 @@
 
 from defaults import kCppUndefinedMacro
 from defaults import kernel_remove_config_macros
+from defaults import kernel_struct_replacements
 from defaults import kernel_token_replacements
 
 
@@ -1215,10 +1216,6 @@
             if b.isIf():
                 b.expr.optimize(macros)
 
-    def removeMacroDefines(self, macros):
-        """Remove known macro definitions from a BlockList."""
-        self.blocks = remove_macro_defines(self.blocks, macros)
-
     def optimizeAll(self, macros):
         self.optimizeMacros(macros)
         self.optimizeIf01()
@@ -1238,7 +1235,7 @@
         for b in self.blocks:
             indent = b.write(out, indent)
 
-    def removeVarsAndFuncs(self, knownStatics=None):
+    def removeVarsAndFuncs(self, keep):
         """Remove variable and function declarations.
 
         All extern and static declarations corresponding to variable and
@@ -1246,7 +1243,7 @@
         enum/structs/union declarations.
 
         However, we keep the definitions corresponding to the set of known
-        static inline functions in the set 'knownStatics', which is useful
+        static inline functions in the set 'keep', which is useful
         for optimized byteorder swap functions and stuff like that.
         """
 
@@ -1262,8 +1259,6 @@
         # state = 2 => var declaration encountered, ends with ";"
         # state = 3 => func declaration encountered, ends with "}"
 
-        if knownStatics is None:
-            knownStatics = set()
         state = 0
         depth = 0
         blocks2 = []
@@ -1319,9 +1314,9 @@
                     # its name.
                     #
                     # We're going to parse the next tokens of the same block
-                    # until we find a semi-column or a left parenthesis.
+                    # until we find a semicolon or a left parenthesis.
                     #
-                    # The semi-column corresponds to a variable definition,
+                    # The semicolon corresponds to a variable definition,
                     # the left-parenthesis to a function definition.
                     #
                     # We also assume that the var/func name is the last
@@ -1355,7 +1350,7 @@
                                       ident)
                         break
 
-                    if ident in knownStatics:
+                    if ident in keep:
                         logging.debug("### keep var/func '%s': %s", ident,
                                       repr(b.tokens[i:j]))
                     else:
@@ -1370,21 +1365,42 @@
                     i += 1
 
                 if i > first:
-                    # print "### final '%s'" % repr(b.tokens[first:i])
+                    #print "### final '%s'" % repr(b.tokens[first:i])
                     blocks2.append(Block(b.tokens[first:i]))
 
         self.blocks = blocks2
 
     def replaceTokens(self, replacements):
         """Replace tokens according to the given dict."""
+        extra_includes = []
         for b in self.blocks:
             made_change = False
             if b.isInclude() is None:
-                for tok in b.tokens:
+                i = 0
+                while i < len(b.tokens):
+                    tok = b.tokens[i]
+                    if (tok.kind == TokenKind.KEYWORD and tok.id == 'struct'
+                        and (i + 2) < len(b.tokens) and b.tokens[i + 2].id == '{'):
+                        struct_name = b.tokens[i + 1].id
+                        if struct_name in kernel_struct_replacements:
+                            extra_includes.append("<bits/%s.h>" % struct_name)
+                            end = i + 2
+                            while end < len(b.tokens) and b.tokens[end].id != '}':
+                                end += 1
+                            end += 1 # Swallow '}'
+                            while end < len(b.tokens) and b.tokens[end].id != ';':
+                                end += 1
+                            end += 1 # Swallow ';'
+                            # Remove these tokens. We'll replace them later with a #include block.
+                            b.tokens[i:end] = []
+                            made_change = True
+                            # We've just modified b.tokens, so revisit the current offset.
+                            continue
                     if tok.kind == TokenKind.IDENTIFIER:
                         if tok.id in replacements:
                             tok.id = replacements[tok.id]
                             made_change = True
+                    i += 1
 
                 if b.isDefine() and b.define_id in replacements:
                     b.define_id = replacements[b.define_id]
@@ -1394,6 +1410,11 @@
                 # Keep 'expr' in sync with 'tokens'.
                 b.expr = CppExpr(b.tokens)
 
+        for extra_include in extra_includes:
+            replacement = CppStringTokenizer(extra_include)
+            self.blocks.insert(2, Block(replacement.tokens, directive='include'))
+
+
 
 def strip_space(s):
     """Strip out redundant space in a given string."""
@@ -1620,19 +1641,6 @@
 ################################################################################
 
 
-def remove_macro_defines(blocks, excludedMacros=None):
-    """Remove macro definitions like #define <macroName>  ...."""
-    if excludedMacros is None:
-        excludedMacros = set()
-    result = []
-    for b in blocks:
-        macroName = b.isDefine()
-        if macroName is None or macroName not in excludedMacros:
-            result.append(b)
-
-    return result
-
-
 def find_matching_endif(blocks, i):
     """Traverse the blocks to find out the matching #endif."""
     n = len(blocks)
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 1afdc77..967d0c7 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -78,34 +78,27 @@
     "SIGRTMAX": "__SIGRTMAX",
     # We want to support both BSD and Linux member names in struct udphdr.
     "udphdr": "__kernel_udphdr",
-    # The kernel's struct epoll_event just has __u64 for the data.
-    "epoll_event": "__kernel_uapi_epoll_event",
     # This causes problems when trying to export the headers for the ndk.
     "__attribute_const__": "__attribute__((__const__))",
+    # In this case the kernel tries to keep out of our way, but we're happy to use its definition.
+    "__kernel_sockaddr_storage": "sockaddr_storage",
     }
 
+
+# This is the set of struct definitions that we want to replace with
+# a #include of <bits/struct.h> instead.
+kernel_struct_replacements = set(
+        [
+          "epoll_event",
+          "in_addr",
+          "ip_mreq_source",
+          "ip_msfilter",
+        ]
+    )
+
+
 # This is the set of known static inline functions that we want to keep
 # in the final kernel headers.
-kernel_known_arm_statics = set(
-        [
-        ]
-    )
-
-kernel_known_arm64_statics = set(
-        [
-        ]
-    )
-
-kernel_known_mips_statics = set(
-        [
-        ]
-    )
-
-kernel_known_x86_statics = set(
-        [
-        ]
-    )
-
 kernel_known_generic_statics = set(
         [
           "ipt_get_target",  # uapi/linux/netfilter_ipv4/ip_tables.h
@@ -133,25 +126,6 @@
         ]
     )
 
-# this maps an architecture to the set of static inline functions that
-# we want to keep in the final headers
-#
-kernel_known_statics = {
-        "arm" : kernel_known_arm_statics,
-        "arm64" : kernel_known_arm64_statics,
-        "mips" : kernel_known_mips_statics,
-        "x86" : kernel_known_x86_statics,
-    }
-
-# this is a list of macros which we want to specifically exclude from
-# the generated files.
-#
-kernel_ignored_macros = set(
-        [
-
-        ]
-    )
-
 # this is the standard disclaimer
 #
 kernel_disclaimer = """\
diff --git a/libc/kernel/uapi/linux/eventpoll.h b/libc/kernel/uapi/linux/eventpoll.h
index d0a5f6e..eec1077 100644
--- a/libc/kernel/uapi/linux/eventpoll.h
+++ b/libc/kernel/uapi/linux/eventpoll.h
@@ -18,6 +18,7 @@
  ****************************************************************************/
 #ifndef _UAPI_LINUX_EVENTPOLL_H
 #define _UAPI_LINUX_EVENTPOLL_H
+#include <bits/epoll_event.h>
 #include <linux/fcntl.h>
 #include <linux/types.h>
 #define EPOLL_CLOEXEC O_CLOEXEC
@@ -44,8 +45,4 @@
 #else
 #define EPOLL_PACKED
 #endif
-struct __kernel_uapi_epoll_event {
-  __u32 events;
-  __u64 data;
-} EPOLL_PACKED;
 #endif
diff --git a/libc/kernel/uapi/linux/if.h b/libc/kernel/uapi/linux/if.h
index d815ef8..15de690 100644
--- a/libc/kernel/uapi/linux/if.h
+++ b/libc/kernel/uapi/linux/if.h
@@ -31,10 +31,27 @@
 #if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 || __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0
 enum net_device_flags {
 #if __UAPI_DEF_IF_NET_DEVICE_FLAGS
-  IFF_UP = 1 << 0, IFF_BROADCAST = 1 << 1, IFF_DEBUG = 1 << 2, IFF_LOOPBACK = 1 << 3, IFF_POINTOPOINT = 1 << 4, IFF_NOTRAILERS = 1 << 5, IFF_RUNNING = 1 << 6, IFF_NOARP = 1 << 7, IFF_PROMISC = 1 << 8, IFF_ALLMULTI = 1 << 9, IFF_MASTER = 1 << 10, IFF_SLAVE = 1 << 11, IFF_MULTICAST = 1 << 12, IFF_PORTSEL = 1 << 13, IFF_AUTOMEDIA = 1 << 14, IFF_DYNAMIC = 1 << 15,
+  IFF_UP = 1 << 0,
+  IFF_BROADCAST = 1 << 1,
+  IFF_DEBUG = 1 << 2,
+  IFF_LOOPBACK = 1 << 3,
+  IFF_POINTOPOINT = 1 << 4,
+  IFF_NOTRAILERS = 1 << 5,
+  IFF_RUNNING = 1 << 6,
+  IFF_NOARP = 1 << 7,
+  IFF_PROMISC = 1 << 8,
+  IFF_ALLMULTI = 1 << 9,
+  IFF_MASTER = 1 << 10,
+  IFF_SLAVE = 1 << 11,
+  IFF_MULTICAST = 1 << 12,
+  IFF_PORTSEL = 1 << 13,
+  IFF_AUTOMEDIA = 1 << 14,
+  IFF_DYNAMIC = 1 << 15,
 #endif
 #if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
-  IFF_LOWER_UP = 1 << 16, IFF_DORMANT = 1 << 17, IFF_ECHO = 1 << 18,
+  IFF_LOWER_UP = 1 << 16,
+  IFF_DORMANT = 1 << 17,
+  IFF_ECHO = 1 << 18,
 #endif
 };
 #endif
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index 351126a..788a6d9 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -18,6 +18,9 @@
  ****************************************************************************/
 #ifndef _UAPI_LINUX_IN_H
 #define _UAPI_LINUX_IN_H
+#include <bits/ip_msfilter.h>
+#include <bits/ip_mreq_source.h>
+#include <bits/in_addr.h>
 #include <linux/types.h>
 #include <linux/libc-compat.h>
 #include <linux/socket.h>
@@ -77,9 +80,6 @@
 };
 #endif
 #if __UAPI_DEF_IN_ADDR
-struct in_addr {
-  __be32 s_addr;
-};
 #endif
 #define IP_TOS 1
 #define IP_TTL 2
@@ -147,36 +147,24 @@
   struct in_addr imr_address;
   int imr_ifindex;
 };
-struct ip_mreq_source {
-  __be32 imr_multiaddr;
-  __be32 imr_interface;
-  __be32 imr_sourceaddr;
-};
-struct ip_msfilter {
-  __be32 imsf_multiaddr;
-  __be32 imsf_interface;
-  __u32 imsf_fmode;
-  __u32 imsf_numsrc;
-  __be32 imsf_slist[1];
-};
 #define IP_MSFILTER_SIZE(numsrc) (sizeof(struct ip_msfilter) - sizeof(__u32) + (numsrc) * sizeof(__u32))
 struct group_req {
   __u32 gr_interface;
-  struct __kernel_sockaddr_storage gr_group;
+  struct sockaddr_storage gr_group;
 };
 struct group_source_req {
   __u32 gsr_interface;
-  struct __kernel_sockaddr_storage gsr_group;
-  struct __kernel_sockaddr_storage gsr_source;
+  struct sockaddr_storage gsr_group;
+  struct sockaddr_storage gsr_source;
 };
 struct group_filter {
   __u32 gf_interface;
-  struct __kernel_sockaddr_storage gf_group;
+  struct sockaddr_storage gf_group;
   __u32 gf_fmode;
   __u32 gf_numsrc;
-  struct __kernel_sockaddr_storage gf_slist[1];
+  struct sockaddr_storage gf_slist[1];
 };
-#define GROUP_FILTER_SIZE(numsrc) (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) + (numsrc) * sizeof(struct __kernel_sockaddr_storage))
+#define GROUP_FILTER_SIZE(numsrc) (sizeof(struct group_filter) - sizeof(struct sockaddr_storage) + (numsrc) * sizeof(struct sockaddr_storage))
 #endif
 #if __UAPI_DEF_IN_PKTINFO
 struct in_pktinfo {
diff --git a/libc/kernel/uapi/linux/rds.h b/libc/kernel/uapi/linux/rds.h
index ccb3f54..cfb0a3b 100644
--- a/libc/kernel/uapi/linux/rds.h
+++ b/libc/kernel/uapi/linux/rds.h
@@ -145,7 +145,7 @@
   __u64 flags;
 };
 struct rds_get_mr_for_dest_args {
-  struct __kernel_sockaddr_storage dest_addr;
+  struct sockaddr_storage dest_addr;
   struct rds_iovec vec;
   __u64 cookie_addr;
   __u64 flags;
diff --git a/libc/kernel/uapi/linux/socket.h b/libc/kernel/uapi/linux/socket.h
index 371ba30..4f52bcb 100644
--- a/libc/kernel/uapi/linux/socket.h
+++ b/libc/kernel/uapi/linux/socket.h
@@ -21,7 +21,7 @@
 #define _K_SS_MAXSIZE 128
 #define _K_SS_ALIGNSIZE (__alignof__(struct sockaddr *))
 typedef unsigned short __kernel_sa_family_t;
-struct __kernel_sockaddr_storage {
+struct sockaddr_storage {
   __kernel_sa_family_t ss_family;
   char __data[_K_SS_MAXSIZE - sizeof(unsigned short)];
 } __attribute__((aligned(_K_SS_ALIGNSIZE)));
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index f5134d6..13354e6 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -188,7 +188,7 @@
 #define TCP_MD5SIG_MAXKEYLEN 80
 #define TCP_MD5SIG_FLAG_PREFIX 1
 struct tcp_md5sig {
-  struct __kernel_sockaddr_storage tcpm_addr;
+  struct sockaddr_storage tcpm_addr;
   __u8 tcpm_flags;
   __u8 tcpm_prefixlen;
   __u16 tcpm_keylen;
diff --git a/libc/kernel/uapi/rdma/rdma_user_cm.h b/libc/kernel/uapi/rdma/rdma_user_cm.h
index 81d963b..24e0f2e 100644
--- a/libc/kernel/uapi/rdma/rdma_user_cm.h
+++ b/libc/kernel/uapi/rdma/rdma_user_cm.h
@@ -82,7 +82,7 @@
   __u32 id;
   __u16 addr_size;
   __u16 reserved;
-  struct __kernel_sockaddr_storage addr;
+  struct sockaddr_storage addr;
 };
 struct rdma_ucm_resolve_ip {
   struct sockaddr_in6 src_addr;
@@ -96,8 +96,8 @@
   __u16 src_size;
   __u16 dst_size;
   __u32 reserved;
-  struct __kernel_sockaddr_storage src_addr;
-  struct __kernel_sockaddr_storage dst_addr;
+  struct sockaddr_storage src_addr;
+  struct sockaddr_storage dst_addr;
 };
 struct rdma_ucm_resolve_route {
   __u32 id;
@@ -129,8 +129,8 @@
   __u16 pkey;
   __u16 src_size;
   __u16 dst_size;
-  struct __kernel_sockaddr_storage src_addr;
-  struct __kernel_sockaddr_storage dst_addr;
+  struct sockaddr_storage src_addr;
+  struct sockaddr_storage dst_addr;
 };
 struct rdma_ucm_query_path_resp {
   __u32 num_paths;
@@ -208,7 +208,7 @@
   __u32 id;
   __u16 addr_size;
   __u16 join_flags;
-  struct __kernel_sockaddr_storage addr;
+  struct sockaddr_storage addr;
 };
 struct rdma_ucm_get_event {
   __u64 response;