summaryrefslogtreecommitdiffstats
path: root/libc/kernel/tools/kernel.py
diff options
context:
space:
mode:
Diffstat (limited to 'libc/kernel/tools/kernel.py')
-rw-r--r--libc/kernel/tools/kernel.py338
1 files changed, 0 insertions, 338 deletions
diff --git a/libc/kernel/tools/kernel.py b/libc/kernel/tools/kernel.py
deleted file mode 100644
index 9d9b5f0..0000000
--- a/libc/kernel/tools/kernel.py
+++ /dev/null
@@ -1,338 +0,0 @@
-# this file contains definitions related to the Linux kernel itself
-#
-
-# list here the macros that you know are always defined/undefined when including
-# the kernel headers
-#
-import sys, cpp, re, os.path, string, time
-from defaults import *
-
-verboseSearch = 0
-verboseFind = 0
-
-########################################################################
-########################################################################
-##### #####
-##### H E A D E R S C A N N E R #####
-##### #####
-########################################################################
-########################################################################
-
-
-class HeaderScanner:
- """a class used to non-recursively detect which Linux kernel headers are
- used by a given set of input source files"""
-
- # to use the HeaderScanner, do the following:
- #
- # scanner = HeaderScanner()
- # for path in <your list of files>:
- # scanner.parseFile(path)
- #
- # # get the set of Linux headers included by your files
- # headers = scanner.getHeaders()
- #
- # # get the set of of input files that do include Linux headers
- # files = scanner.getFiles()
- #
- # note that the result of getHeaders() is a set of strings, each one
- # corresponding to a non-bracketed path name, e.g.:
- #
- # set("linux/types","asm/types.h")
- #
-
- # the default algorithm is pretty smart and will analyze the input
- # files with a custom C pre-processor in order to optimize out macros,
- # get rid of comments, empty lines, etc..
- #
- # this avoids many annoying false positives... !!
- #
-
- # this regular expression is used to detect include paths that relate to
- # the kernel, by default, it selects one of:
- # <linux/*>
- # <asm/*>
- # <asm-generic/*>
- # <mtd/*>
- #
- re_combined =\
- re.compile(r"^.*<((%s)/[\d\w_\+\.\-/]*)>.*$" % string.join(kernel_dirs,"|") )
- # some kernel files choose to include files with relative paths (x86 32/64
- # dispatch for instance)
- re_rel_dir = re.compile(r'^.*"([\d\w_\+\.\-/]+)".*$')
-
- def __init__(self,config={}):
- """initialize a HeaderScanner"""
- self.reset()
- self.config = config
-
- def reset(self,config={}):
- self.files = set() # set of files being parsed for headers
- self.headers = {} # maps headers to set of users
- self.config = config
-
- def checkInclude(self, line, from_file, kernel_root=None):
- relative = False
- m = HeaderScanner.re_combined.match(line)
- if kernel_root and not m:
- m = HeaderScanner.re_rel_dir.match(line)
- relative = True
- if not m: return
-
- header = m.group(1)
- if from_file:
- self.files.add(from_file)
- if kernel_root and relative:
- hdr_dir = os.path.realpath(os.path.dirname(from_file))
- hdr_dir = hdr_dir.replace("%s/" % os.path.realpath(kernel_root),
- "")
- if hdr_dir:
- _prefix = "%s/" % hdr_dir
- else:
- _prefix = ""
- header = "%s%s" % (_prefix, header)
-
- if not header in self.headers:
- self.headers[header] = set()
-
- if from_file:
- if verboseFind:
- print "=== %s uses %s" % (from_file, header)
- self.headers[header].add(from_file)
-
- def parseFile(self, path, arch=None, kernel_root=None):
- """parse a given file for Linux headers"""
- if not os.path.exists(path):
- return
-
- # since tokenizing the file is very slow, we first try a quick grep
- # to see if this returns any meaningful results. only if this is true
- # do we do the tokenization"""
- try:
- f = open(path, "rt")
- except:
- print "!!! can't read '%s'" % path
- return
-
- hasIncludes = False
- for line in f:
- if (HeaderScanner.re_combined.match(line) or
- (kernel_root and HeaderScanner.re_rel_dir.match(line))):
- hasIncludes = True
- break
-
- if not hasIncludes:
- if verboseSearch: print "::: " + path
- return
-
- if verboseSearch: print "*** " + path
-
- list = cpp.BlockParser().parseFile(path)
- if list:
- #list.removePrefixed("CONFIG_",self.config)
- macros = kernel_known_macros.copy()
- if kernel_root:
- macros.update(self.config)
- if arch and arch in kernel_default_arch_macros:
- macros.update(kernel_default_arch_macros[arch])
- list.optimizeMacros(macros)
- list.optimizeIf01()
- includes = list.findIncludes()
- for inc in includes:
- self.checkInclude(inc, path, kernel_root)
-
- def getHeaders(self):
- """return the set of all needed kernel headers"""
- return set(self.headers.keys())
-
- def getHeaderUsers(self,header):
- """return the set of all users for a given header"""
- return set(self.headers.get(header))
-
- def getAllUsers(self):
- """return a dictionary mapping heaaders to their user set"""
- return self.headers.copy()
-
- def getFiles(self):
- """returns the set of files that do include kernel headers"""
- return self.files.copy()
-
-
-##########################################################################
-##########################################################################
-##### #####
-##### H E A D E R F I N D E R #####
-##### #####
-##########################################################################
-##########################################################################
-
-
-class KernelHeaderFinder:
- """a class used to scan the kernel headers themselves."""
-
- # this is different
- # from a HeaderScanner because we need to translate the path returned by
- # HeaderScanner.getHeaders() into possibly architecture-specific ones.
- #
- # for example, <asm/XXXX.h> needs to be translated in <asm-ARCH/XXXX.h>
- # where ARCH is appropriately chosen
-
- # here's how to use this:
- #
- # scanner = HeaderScanner()
- # for path in <your list of user sources>:
- # scanner.parseFile(path)
- #
- # used_headers = scanner.getHeaders()
- # finder = KernelHeaderFinder(used_headers, [ "arm", "x86" ],
- # "<kernel_include_path>")
- # all_headers = finder.scanForAllArchs()
- #
- # not that the result of scanForAllArchs() is a list of relative
- # header paths that are not bracketed
- #
-
- def __init__(self,headers,archs,kernel_root,kernel_config):
- """init a KernelHeaderScanner,
-
- 'headers' is a list or set of headers,
- 'archs' is a list of architectures
- 'kernel_root' is the path to the 'include' directory
- of your original kernel sources
- """
-
- if len(kernel_root) > 0 and kernel_root[-1] != "/":
- kernel_root += "/"
- #print "using kernel_root %s" % kernel_root
- self.archs = archs
- self.searched = set(headers)
- self.kernel_root = kernel_root
- self.kernel_config = kernel_config
- self.needed = {}
- self.setArch(arch=None)
-
- def setArch(self,arch=None):
- self.curr_arch = arch
- self.arch_headers = set()
- if arch:
- self.prefix = "asm-%s/" % arch
- else:
- self.prefix = None
-
- def pathFromHeader(self,header):
- path = header
- if self.prefix and path.startswith("asm/"):
- path = "%s%s" % (self.prefix, path[4:])
- return path
-
- def pathToHeader(self,path):
- if self.prefix and path.startswith(self.prefix):
- path = "asm/%s" % path[len(self.prefix):]
- return "%s" % path
-
- def setSearchedHeaders(self,headers):
- self.searched = set(headers)
-
- def scanForArch(self):
- fparser = HeaderScanner(config=self.kernel_config)
- workqueue = []
- needed = {}
- for h in self.searched:
- path = self.pathFromHeader(h)
- if not path in needed:
- needed[path] = set()
- workqueue.append(path)
-
- i = 0
- while i < len(workqueue):
- path = workqueue[i]
- i += 1
- fparser.parseFile(self.kernel_root + path,
- arch=self.curr_arch, kernel_root=self.kernel_root)
- for used in fparser.getHeaders():
- path = self.pathFromHeader(used)
- if not path in needed:
- needed[path] = set()
- workqueue.append(path)
- for user in fparser.getHeaderUsers(used):
- needed[path].add(user)
-
- # now copy the arch-specific headers into the global list
- for header in needed.keys():
- users = needed[header]
- if not header in self.needed:
- self.needed[header] = set()
-
- for user in users:
- self.needed[header].add(user)
-
- def scanForAllArchs(self):
- """scan for all architectures and return the set of all needed kernel headers"""
- for arch in self.archs:
- self.setArch(arch)
- self.scanForArch()
-
- return set(self.needed.keys())
-
- def getHeaderUsers(self,header):
- """return the set of all users for a given header"""
- return set(self.needed[header])
-
- def getArchHeaders(self,arch):
- """return the set of all <asm/...> headers required by a given architecture"""
- return set() # XXX: TODO
-
-#####################################################################################
-#####################################################################################
-##### #####
-##### C O N F I G P A R S E R #####
-##### #####
-#####################################################################################
-#####################################################################################
-
-class ConfigParser:
- """a class used to parse the Linux kernel .config file"""
- re_CONFIG_ = re.compile(r"^(CONFIG_\w+)=(.*)$")
-
- def __init__(self):
- self.items = {}
- self.duplicates = False
-
- def parseLine(self,line):
- line = string.strip(line)
-
- # skip empty and comment lines
- if len(line) == 0 or line[0] == "#":
- return
-
- m = ConfigParser.re_CONFIG_.match(line)
- if not m: return
-
- name = m.group(1)
- value = m.group(2)
-
- if name in self.items: # aarg, duplicate value
- self.duplicates = True
-
- self.items[name] = value
-
- def parseFile(self,path):
- f = file(path, "r")
- for line in f:
- if len(line) > 0:
- if line[-1] == "\n":
- line = line[:-1]
- if len(line) > 0 and line[-1] == "\r":
- line = line[:-1]
- self.parseLine(line)
- f.close()
-
- def getDefinitions(self):
- """retrieve a dictionary containing definitions for CONFIG_XXX"""
- return self.items.copy()
-
- def __repr__(self):
- return repr(self.items)
-
- def __str__(self):
- return str(self.items)