diff options
Diffstat (limited to 'libc/kernel/tools/kernel.py')
-rw-r--r-- | libc/kernel/tools/kernel.py | 338 |
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) |