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
208integers = inttypes[arch].keys();
209integers.sort(lambda a, b: cmp(len(b),len(a)));
210for type in integers:
211    output = re.sub("\\b%s\\b" % type, inttypes[arch][type], output);
212
213# print results
214f = open(outfile, "w");
215f.write(output);
216f.close;
217
218