From 5c87e6c6b0374b346afdd2f0f9e9dd2fd93cf7ba Mon Sep 17 00:00:00 2001 From: Martin Fouilleul Date: Thu, 3 Aug 2023 14:50:39 +0200 Subject: [PATCH] [gles bindings] do some bounds checking for argument-based array lengths --- scripts/bindgen.py | 91 +++++++++++++++++++++++++++++++++------------ scripts/gles_gen.py | 8 +++- 2 files changed, 75 insertions(+), 24 deletions(-) diff --git a/scripts/bindgen.py b/scripts/bindgen.py index 48baa0e..e04433a 100755 --- a/scripts/bindgen.py +++ b/scripts/bindgen.py @@ -115,9 +115,75 @@ for decl in data: if gen_stub == False: s += ';\n\n' else: - s += '\n{\n\t' + s += '\n{\n' + + + # NOTE: check and cast arguments retTag = decl['ret']['tag'] + firstArgIndex = 0 + if retTag != 'v': + firstArgIndex = 1 + + for argIndex, arg in enumerate(decl['args']): + + argName = arg['name'] + typeName = arg['type']['name'] + typeCName = arg['type'].get('cname', typeName) + argTag = arg['type']['tag'] + + s += '\t' + + if argTag == 'i': + s += typeCName + ' ' + argName + ' = *(i32*)&_sp[' + str(firstArgIndex + argIndex) + '];\n' + elif argTag == 'I': + s += typeCName + ' ' + argName + ' = *(i64*)&_sp[' + str(firstArgIndex + argIndex) + '];\n' + elif argTag == 'f': + s += typeCName + ' ' + argName + ' = *(f32*)&_sp[' + str(firstArgIndex + argIndex) + '];\n' + elif argTag == 'F': + s += typeCName + ' ' + argName + ' = *(f64*)&_sp[' + str(firstArgIndex + argIndex) + '];\n' + elif argTag == 'p': + s += typeCName + ' ' + argName + ' = ('+ typeCName +')((char*)_mem + *(i32*)&_sp[' + str(firstArgIndex + argIndex) + ']);\n' + elif argTag == 'S': + s += typeCName + ' ' + argName + ' = *('+ typeCName +'*)((char*)_mem + *(i32*)&_sp[' + str(firstArgIndex + argIndex) + ']);\n' + else: + print('unrecognized type ' + c + ' in procedure signature\n') + break + + # check pointer arg length + for arg in decl['args']: + + argName = arg['name'] + typeName = arg['type']['name'] + typeCName = arg['type'].get('cname', typeName) + argTag = arg['type']['tag'] + argLen = arg.get('len') + + if argTag == 'p' and argLen != None: + + components = argLen.get('components') + countArg = argLen.get('count') + + s += '\tASSERT((char*)' + argName + ' + ' + + if components != None: + s += str(components) + if countArg != None: + s += '*' + if countArg != None: + s += countArg + + if typeCName.startswith('void') == False and typeCName.startswith('const void') == False: + s += '*sizeof('+typeCName+')' + + s += ' < ((char*)_mem + m3_GetMemorySize(runtime)));\n' + + ############################################################################## + #TODO: make sure return slot can contain return type + ############################################################################## + + s += '\t' + if retTag == 'i': s += '*((i32*)&_sp[0]) = ' elif retTag == 'I': @@ -133,29 +199,8 @@ for decl in data: s += cname + '(' - firstArgIndex = 0 - if retTag != 'v': - firstArgIndex = 1 - for i, arg in enumerate(decl['args']): - typeName = arg['type']['name'] - typeCName = arg['type'].get('cname', typeName) - argTag = arg['type']['tag'] - if argTag == 'i': - s += '*(i32*)&_sp[' + str(firstArgIndex + i) + ']' - elif argTag == 'I': - s += '*(i64*)&_sp[' + str(firstArgIndex + i) + ']' - elif argTag == 'f': - s += '*(f32*)&_sp[' + str(firstArgIndex + i) + ']' - elif argTag == 'F': - s += '*(f64*)&_sp[' + str(firstArgIndex + i) + ']' - elif argTag == 'p': - s += '(void*)((char*)_mem + *(i32*)&_sp[' + str(firstArgIndex + i) + '])' - elif argTag == 'S': - s += '*(' + typeCName + '*)((char*)_mem + *(i32*)&_sp[' + str(firstArgIndex + i) + '])' - else: - print('unrecognized type ' + c + ' in procedure signature\n') - break + s += arg['name'] if i+1 < len(decl['args']): s += ', ' diff --git a/scripts/gles_gen.py b/scripts/gles_gen.py index f4668de..0d45fa3 100644 --- a/scripts/gles_gen.py +++ b/scripts/gles_gen.py @@ -22,10 +22,13 @@ def gen_gles_header(spec, filename): tree = et.parse(spec) reg.loadElementTree(tree) - gen = COutputGenerator() + logFile = open('./gles_gen.log', 'w') + gen = COutputGenerator(diagFile=logFile) reg.setGenerator(gen) reg.apiGen(genOpts) + logFile.close() + def get_bindgen_tag_for_type(typeName): typeToTags = { @@ -159,6 +162,9 @@ def gen_gles_bindgen_json(spec, filename): typeName = typeName.strip() + if typeName.endswith('**'): + print("Warning: function " + name + ": parameter " + argName + " has 2 (or more) levels of indirection") + typeTag = get_bindgen_tag_for_type(typeName) if typeTag == None: