1#!/usr/bin/python
2
3import sys, re;
4from structs import unions, structs, defines;
5
6# command line arguments
7arch    = sys.argv[1];
8outfile = sys.argv[2];
9infiles = sys.argv[3:];
10
11
12###########################################################################
13# configuration #2: architecture information
14
15inttypes = {};
16header = {};
17footer = {};
18
19#arm
20inttypes["arm32"] = [
21    ("unsigned long", "__danger_unsigned_long_on_arm32"),
22    ("long",          "__danger_long_on_arm32"),
23    ("xen_pfn_t",     "uint64_t"),
24    ("xen_ulong_t",   "uint64_t"),
25    ("uint64_t",      "__align8__ uint64_t"),
26]
27header["arm32"] = """
28#define __arm___ARM32 1
29#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
30# define __DECL_REG(n64, n32) union { uint64_t n64; uint32_t n32; }
31# define __align8__ __attribute__((aligned (8)))
32#else
33# define __DECL_REG(n64, n32) uint64_t n64
34# define __align8__ FIXME
35#endif
36""";
37footer["arm32"] = """
38#undef __DECL_REG
39"""
40
41inttypes["arm64"] = [
42    ("unsigned long", "__danger_unsigned_long_on_arm64"),
43    ("long",          "__danger_long_on_arm64"),
44    ("xen_pfn_t",     "uint64_t"),
45    ("xen_ulong_t",   "uint64_t"),
46    ("uint64_t",      "__align8__ uint64_t"),
47]
48header["arm64"] = """
49#define __aarch64___ARM64 1
50#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
51# define __DECL_REG(n64, n32) union { uint64_t n64; uint32_t n32; }
52# define __align8__ __attribute__((aligned (8)))
53#else
54# define __DECL_REG(n64, n32) uint64_t n64
55# define __align8__ FIXME
56#endif
57""";
58footer["arm64"] = """
59#undef __DECL_REG
60"""
61
62# x86_32
63inttypes["x86_32"] = [
64    ("unsigned long", "uint32_t"),
65    ("long",          "uint32_t"),
66    ("xen_pfn_t",     "uint32_t"),
67    ("xen_ulong_t",   "uint32_t"),
68]
69header["x86_32"] = """
70#define __DECL_REG_LO8(which) uint32_t e ## which ## x
71#define __DECL_REG_LO16(name) uint32_t e ## name
72#define __i386___X86_32 1
73#pragma pack(4)
74""";
75footer["x86_32"] = """
76#undef __DECL_REG_LO8
77#undef __DECL_REG_LO16
78#pragma pack()
79""";
80
81# x86_64
82inttypes["x86_64"] = [
83    ("unsigned long", "__align8__ uint64_t"),
84    ("long",          "__align8__ uint64_t"),
85    ("xen_pfn_t",     "__align8__ uint64_t"),
86    ("xen_ulong_t",   "__align8__ uint64_t"),
87]
88header["x86_64"] = """
89#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
90# define __DECL_REG(name) union { uint64_t r ## name, e ## name; }
91# define __align8__ __attribute__((aligned (8)))
92#else
93# define __DECL_REG(name) uint64_t r ## name
94# define __align8__ FIXME
95#endif
96#define __DECL_REG_LOHI(name) __DECL_REG(name ## x)
97#define __DECL_REG_LO8        __DECL_REG
98#define __DECL_REG_LO16       __DECL_REG
99#define __DECL_REG_HI         __DECL_REG
100#define __x86_64___X86_64 1
101""";
102footer["x86_64"] = """
103#undef __DECL_REG
104#undef __DECL_REG_LOHI
105#undef __DECL_REG_LO8
106#undef __DECL_REG_LO16
107#undef __DECL_REG_HI
108"""
109
110###########################################################################
111# main
112
113input  = "";
114output = "";
115fileid = re.sub("[-.]", "_", "__FOREIGN_%s__" % outfile.upper());
116
117# read input header files
118for name in infiles:
119    f = open(name, "r");
120    input += f.read();
121    f.close();
122
123# add header
124output += """
125/*
126 * public xen defines and struct for %s
127 * generated by %s -- DO NOT EDIT
128 */
129
130#ifndef %s
131#define %s 1
132
133""" % (arch, sys.argv[0], fileid, fileid)
134
135if arch in header:
136    output += header[arch];
137    output += "\n";
138
139defined = {}
140
141# add defines to output
142for line in re.findall("#define[^\n]+", input):
143    for define in defines:
144        regex = "#define\s+%s\\b" % define;
145        match = re.search(regex, line);
146        if None == match:
147            continue;
148        defined[define] = 1
149        if define.upper()[0] == define[0]:
150            replace = define + "_" + arch.upper();
151        else:
152            replace = define + "_" + arch;
153        regex = "\\b%s\\b" % define;
154        output += re.sub(regex, replace, line) + "\n";
155output += "\n";
156
157# delete defines, comments, empty lines
158input = re.sub("#define[^\n]+\n", "", input);
159input = re.compile("/\*(.*?)\*/", re.S).sub("", input)
160input = re.compile("\n\s*\n", re.S).sub("\n", input);
161
162# add unions to output
163for union in unions:
164    regex = "union\s+%s\s*\{(.*?)\n\};" % union;
165    match = re.search(regex, input, re.S)
166    if None == match:
167        output += "#define %s_has_no_%s 1\n" % (arch, union);
168    else:
169        output += "union %s_%s {%s\n};\n" % (union, arch, match.group(1));
170    output += "\n";
171
172# add structs to output
173for struct in structs:
174    regex = "(?:#ifdef ([A-Z_]+))?\nstruct\s+%s\s*\{(.*?)\n\};" % struct;
175    match = re.search(regex, input, re.S)
176    if None == match or \
177           (match.group(1) is not None and match.group(1) not in defined):
178        output += "#define %s_has_no_%s 1\n" % (arch, struct);
179    else:
180        output += "struct %s_%s {%s\n};\n" % (struct, arch, match.group(2));
181        output += "typedef struct %s_%s %s_%s_t;\n" % (struct, arch, struct, arch);
182    output += "\n";
183
184# add footer
185if arch in footer:
186    output += footer[arch];
187    output += "\n";
188output += "#endif /* %s */\n" % fileid;
189
190# replace: defines
191for define in defines:
192    if define.upper()[0] == define[0]:
193        replace = define + "_" + arch.upper();
194    else:
195        replace = define + "_" + arch;
196    output = re.sub("\\b%s\\b" % define, replace, output);
197
198# replace: unions
199for union in unions:
200    output = re.sub("\\b(union\s+%s)\\b" % union, "\\1_%s" % arch, output);
201
202# replace: structs + struct typedefs
203for struct in structs:
204    output = re.sub("\\b(struct\s+%s)\\b" % struct, "\\1_%s" % arch, output);
205    output = re.sub("\\b(%s)_t\\b" % struct, "\\1_%s_t" % arch, output);
206
207# replace: integer types
208for old, new in inttypes[arch]:
209    output = re.sub("\\b%s\\b" % old, new, output)
210
211# print results
212f = open(outfile, "w");
213f.write(output);
214f.close;
215
216