diff options
Diffstat (limited to 'main.py')
-rwxr-xr-x | main.py | 117 |
1 files changed, 115 insertions, 2 deletions
@@ -60,6 +60,57 @@ def type_resolver(elem, elem_list): return node.attrib["name"] else: return type_str +def get_malloc_size(node, elem_list): + void_count = 0 + numeric_count = 0 + has_special = False + for child in node: + if type_str == "int8": numeric_count+=1 + elif type_str == "uint8": numeric_count+=1 + elif type_str == "int16": numeric_count+=2 + elif type_str == "uint16": numeric_count+=2 + elif type_str == "int32": numeric_count+=3 + elif type_str == "uint32": numeric_count+=3 + elif type_str == "int64": numeric_count+=8 + elif type_str == "uint64": numeric_count+=8 + elif type_str == "int128": numeric_count+=16 + elif type_str == "uint128": numeric_count+=16 + elif type_str == "float": numeric_count+=32 + elif type_str == "double": numeric_count+=64 + elif type_str == "bool": numeric_count+=1 + elif type_str == "uchar": numeric_count+=1 + elif type_str == "schar": numeric_count+=1 + elif type_str == "string": has_special = True + elif type_str == "FT::conditional": pass + elif type_str.find("self::") == 0: void_count+=1 + else: pass + +def get_type_width(elem): + type_str = str() + try: + type_str = elem.attrib["type"] + except KeyError: + print("xml node does not have a type attribute: " + elem.tag) + if type_str == "int8": return 1 + elif type_str == "uint8": return 1 + elif type_str == "int16": return 2 + elif type_str == "uint16": return 2 + elif type_str == "int32": return 4 + elif type_str == "uint32": return 4 + elif type_str == "int64": return 8 + elif type_str == "uint64": return 8 + elif type_str == "int128": return 16 + elif type_str == "uint128": return 16 + elif type_str == "float": return 4 + elif type_str == "double": return 8 + elif type_str == "bool": return 1 + elif type_str == "uchar": return 1 + elif type_str == "schar": return 1 + elif type_str == "string": return 0 + elif type_str == "FT::conditional": return 0 + elif type_str.find("self::") == 0: return 0 + else: return 0 + def get_def_node(type_str, elem_list): for node in elem_list: if type_str == node.attrib["name"]: @@ -124,6 +175,12 @@ class Argparser(object): parser.add_argument("--inline", action="store_true", help="inlines reader funcs", default=False) parser.add_argument("--static", action="store_true", help="statics reader funcs", default=False) parser.add_argument("--verbose", action="store_true", help="verbose", default=False) + # TODO + parser.add_argument("--forcenullterm", action="store_true", help="terminate all strings with null even if they are not null-terminated", default=False) + # TODO + parser.add_argument("--buffersize", type=int, help="the size of the buffer for special reads(e.g. strings)", default=100) + # TODO + parser.add_argument("--buffgrowfactor", type=float, help="main target name", default=1.6) self.args = parser.parse_args() def dupemake(path, main_name): @@ -144,6 +201,7 @@ class CodeGen(object): self.read_elems = [] self.read_iter = [] self.def_iter = [] + self.mem_size = {} def init_hook(self): pass @@ -166,6 +224,10 @@ class CodeGen(object): print("XXXX " + elem.tag) print(elem.attrib) + def dump_mem_dict(self): + for key, value in self.mem_size.items(): + print(key + ".." + value) + def gen_reader_funcs(self): temp_dec_list = [] read_source = open(self.argparser.args.outdir + "/read.c", "w") @@ -232,7 +294,7 @@ class CodeGen(object): if child_count == 1: read_source.write(for_read) elif child_count > 1: - read_source.write(text.simple_loop.replace("YYY", for_read).repalce("XXX", str(child_count))) + read_source.write(text.simple_loop.replace("YYY", for_read).replace("XXX", str(child_count))) else: # child_count = -1 count_name_str = child.attrib["count"][6:] read_source.write(text.simple_loop.replace("YYY", for_read).replace("XXX", "dummy->" + get_node_name(count_name_str, elem))) @@ -248,9 +310,58 @@ class CodeGen(object): #read_source.write(text.c_function_return_type) read_source.write(text.c_function_close + "\n") + def gen_void_train(self): + void_source = open(self.argparser.args.outdir + "/void.h", "w") + void_source.write("\n// automatically generated by faultreiber\n") + void_source.write("// " + self.dnt + "\n") + void_source.write('#include "./structs.h"\n') + void_source.write('#include "./read.c"\n') + void_source.write("#include <stdlib.h>\n") + void_source.write("void** void_train(void) {\n") + count_int = int() + count_void = int() + read_count = len(self.read_elems) + for elem in self.read_elems + self.def_elems: + if "isaggregate" in elem.attrib: + for child in elem: + count = get_elem_count(child, self.def_elems + self.read_elems) + size = get_elem_size(child, self.def_elems + self.read_elems) + type_width = get_type_width(child) + #print(child.tag + ":" + str(type_width)) + if "count" in child.attrib: pass + if "size" in child.attrib: pass + if count > 0: count_int+=count*type_width + if count < 0: count_void+=1 + if size > 0: count_int+=size + if size < 0: count_void+=1 + self.mem_size[elem.attrib["name"]] = (str(count_int)+"+" if count_int > 0 else "") + (str(count_void)+"*"+"sizeof(void*)") if count_void > 0 else "" + count_int = 0 + count_void = 0 + else: + if "size" in elem.attrib: + count = get_elem_count(elem, self.def_elems + self.read_elems) + if count > 0: count_int+= count + else: count_void+=1 + if "count" in elem.attrib: + size = get_elem_size(elem, self.def_elems + self.read_elems) + if size > 0: count_int+=size + else: count_void+=1 + #void_source.write("void* ptr = malloc(sizeof(void*));\n") + self.mem_size[elem.attrib["name"]] = (str(count_int)+"+" if count_int > 0 else "") + (str(count_void)+"*"+"sizeof(void*)") if count_void > 0 else "" + count_int = 0 + count_void = 0 + void_source.write("}") + def gen_aggregate_read(self): + agg_source = open(self.argparser.args.outdir + "/aggregate.h", "w") + agg_source.write("\n// automatically generated by faultreiber\n") + agg_source.write("// " + self.dnt + "\n") + agg_source.write('#include "./structs.h"\n') + agg_source.write('#include "./read.c"\n') + agg_source.write("void read_aggr(void) {\n") for elem in self.read_elems: - pass + agg_source.write("ft_read_" + elem.attrib["name"] + "(_fd, );\n") + agg_source.write("}") def read_xml(self): if self.argparser.args.xml: @@ -371,7 +482,9 @@ class CodeGen(object): self.gen_struct_header_xml() #self.dump_def_elems() #self.dump_read_elems() + self.gen_void_train() self.gen_aggregate_read() + self.dump_mem_dict() # write code here def premain(argparser): |