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