sel_ldr: Remove support for rodata segment at start of executable
[nativeclient.git] / service_runtime / nacl_syscall_handlers_gen2.py
blob44546ad4fd50a0cdac21781b9d3e11e5aae9337d
1 #!/usr/bin/python
2 # Copyright 2008, Google Inc.
3 # All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met:
8 #
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following disclaimer
13 # in the documentation and/or other materials provided with the
14 # distribution.
15 # * Neither the name of Google Inc. nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 # This script extracts "nacl syscall" prototypes from a c file
33 # given on stdin and then produces wrapped versions of the syscalls.
35 # NOTE: Please use care to maintain python 2.3 compatibility, for
36 # portability.
38 import getopt
39 import re
40 import string
41 import sys
43 AUTOGEN_COMMENT = """\
45 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
47 * Automatically generated code. See nacl_syscall_handlers_gen.py
49 * NaCl Server Runtime Service Call abstractions
51 """
54 TABLE_INITIALIZER = """\
56 /* auto generated */
58 void NaClSyscallTableInit() {
59 int i;
60 for (i = 0; i < NACL_MAX_SYSCALLS; ++i) {
61 nacl_syscall[i].handler = &NotImplementedDecoder;
66 """
69 IMPLEMENTATION_SKELETON = """\
70 /* this function was automagically generated */
71 static int32_t %(name)sDecoder(struct NaClAppThread *natp) {
72 %(members)s\
73 return %(name)s(natp%(arglist)s);
75 """
77 def FunctionNameToSyscallDefine(name):
78 assert name.startswith("NaClSys")
79 name = name[7:]
80 return "NACL_sys_" + name.lower()
82 def ParamList(alist):
83 if not alist:
84 return ''
85 return ', ' + ', '.join(alist)
88 def ExtractVariable(decl):
89 type_or_idents = re.findall(r'[a-zA-Z][-_a-zA-Z]*', decl)
90 return type_or_idents[len(type_or_idents)-1]
93 def ArgList(alist):
94 if not alist:
95 return ''
96 # Note: although this return value might be computed more
97 # concisely with a list comprehension, we instead use a
98 # for statement to maintain python 2.3 compatibility.
99 extractedargs = []
100 for arg in alist:
101 extractedargs += ['p.' + ExtractVariable(arg)]
102 return ', ' + ', '.join(extractedargs)
105 def MemberList(name, alist):
106 if not alist:
107 return ''
109 # Note: although this return value might be computed more
110 # concisely with a list comprehension, we instead use a
111 # for statement to maintain python 2.3 compatibility.
112 margs = []
113 for arg in alist:
114 margs += [' ' + arg]
115 values = {
116 'name': name,
117 'members' : ';\n'.join(margs) + ';'
120 return """\
121 struct %(name)sArgs {
122 %(members)s
123 } p = *(struct %(name)sArgs *) natp->x_esp;
125 """ % values
128 def PrintSyscallTableIntializer(protos, ostr):
129 assign = []
130 for name, _ in protos:
131 syscall = FunctionNameToSyscallDefine(name)
132 assign.append(" NaClAddSyscall(%s, &%sDecoder);" % (syscall, name))
133 print >>ostr, TABLE_INITIALIZER % "\n".join(assign)
136 def PrintImplSkel(protos, ostr):
137 print >>ostr, AUTOGEN_COMMENT;
138 for name, alist in protos:
139 values = { 'name' : name,
140 'paramlist' : ParamList(alist[1:]),
141 'arglist' : ArgList(alist[1:]),
142 'members' : MemberList(name, alist[1:]),
144 print >>ostr, IMPLEMENTATION_SKELETON % values
147 def GetProtoArgs(s, fin):
148 if "{" not in s:
149 for line in fin:
150 s += line
151 if "{" in line:
152 break
153 else:
154 # broken input
155 assert 0
156 pos = s.rfind(")")
157 assert pos >= 0
158 # prune stuff after )
159 s = s[0:pos]
160 args = [a.strip() for a in s.split(",")]
161 return args
164 def ParseFileToBeWrapped(fin, filter_regex):
165 protos = []
166 for line in fin:
167 match = re.search(r"^int32_t (NaClSys[_a-zA-Z0-9]+)[(](.*)$", line)
168 if not match:
169 continue
170 name = match.group(1)
171 args = GetProtoArgs(match.group(2), fin)
172 if filter_regex and re.search(filter_regex, name):
173 continue
174 protos.append( (name, args) )
175 return protos
178 def main(argv):
179 usage='Usage: nacl_syscall_handlers_gen.py [-f regex] [-c] [-d]'
180 filter_regex = ""
181 mode = "dump"
182 try:
183 opts, pargs = getopt.getopt(argv[1:], 'hcdf:')
184 except getopt.error, e:
185 print >>sys.stderr, 'Illegal option:', str(e)
186 print >>sys.stderr, usage
187 return 1
189 for opt, val in opts:
190 if opt == '-d':
191 mode = "dump"
192 elif opt == '-c':
193 mode = "codegen"
194 elif opt == '-f':
195 filter_regex = val
196 else:
197 assert 0
199 protos = ParseFileToBeWrapped(sys.stdin, filter_regex)
200 if mode == "dump":
201 for f, a in protos:
202 print f
203 print "\t", a
204 elif mode == "header":
205 PrintHeaderFile(protos, sys.stdout)
206 elif mode == "codegen":
207 PrintImplSkel(protos, sys.stdout)
208 PrintSyscallTableIntializer(protos, sys.stdout)
211 return 0
214 if __name__ == '__main__':
215 sys.exit(main(sys.argv))