[gles bindings] do some bounds checking for argument-based array lengths

This commit is contained in:
Martin Fouilleul 2023-08-03 14:50:39 +02:00
parent a33a978415
commit 5c87e6c6b0
2 changed files with 75 additions and 24 deletions

View File

@ -115,9 +115,75 @@ for decl in data:
if gen_stub == False: if gen_stub == False:
s += ';\n\n' s += ';\n\n'
else: else:
s += '\n{\n\t' s += '\n{\n'
# NOTE: check and cast arguments
retTag = decl['ret']['tag'] 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': if retTag == 'i':
s += '*((i32*)&_sp[0]) = ' s += '*((i32*)&_sp[0]) = '
elif retTag == 'I': elif retTag == 'I':
@ -133,29 +199,8 @@ for decl in data:
s += cname + '(' s += cname + '('
firstArgIndex = 0
if retTag != 'v':
firstArgIndex = 1
for i, arg in enumerate(decl['args']): for i, arg in enumerate(decl['args']):
typeName = arg['type']['name'] s += arg['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
if i+1 < len(decl['args']): if i+1 < len(decl['args']):
s += ', ' s += ', '

View File

@ -22,10 +22,13 @@ def gen_gles_header(spec, filename):
tree = et.parse(spec) tree = et.parse(spec)
reg.loadElementTree(tree) reg.loadElementTree(tree)
gen = COutputGenerator() logFile = open('./gles_gen.log', 'w')
gen = COutputGenerator(diagFile=logFile)
reg.setGenerator(gen) reg.setGenerator(gen)
reg.apiGen(genOpts) reg.apiGen(genOpts)
logFile.close()
def get_bindgen_tag_for_type(typeName): def get_bindgen_tag_for_type(typeName):
typeToTags = { typeToTags = {
@ -159,6 +162,9 @@ def gen_gles_bindgen_json(spec, filename):
typeName = typeName.strip() 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) typeTag = get_bindgen_tag_for_type(typeName)
if typeTag == None: if typeTag == None: