vrclient: Fixup size for structs with matching field offsets but mismatched size.

CW-Bug-Id: 19067
This commit is contained in:
Paul Gofman 2021-07-09 01:42:07 +03:00 committed by Andrew Eikum
parent ed7c5db865
commit d46e6aaada
8 changed files with 50 additions and 14 deletions

View File

@ -280,6 +280,7 @@ skip_structs = [
] ]
struct_conversion_cache = {} struct_conversion_cache = {}
struct_needs_size_adjustment_cache = {}
print_sizes = [] print_sizes = []
@ -470,6 +471,7 @@ def handle_method(cfile, classname, winclassname, cppname, method, cpp, cpp_h, e
unnamed = 'a' unnamed = 'a'
do_lin_to_win = None do_lin_to_win = None
do_win_to_lin = None do_win_to_lin = None
do_size_fixup = None
do_wrap = None do_wrap = None
do_unwrap = None do_unwrap = None
need_convert = [] need_convert = []
@ -498,6 +500,10 @@ def handle_method(cfile, classname, winclassname, cppname, method, cpp, cpp_h, e
do_lin_to_win = (strip_const(strip_ns(real_type.get_canonical().spelling)), param.spelling) do_lin_to_win = (strip_const(strip_ns(real_type.get_canonical().spelling)), param.spelling)
#preserve pointers #preserve pointers
typename = typename.replace(strip_ns(real_type.spelling), "win%s_%s" % (strip_ns(real_type.get_canonical().spelling), display_sdkver(sdkver))) typename = typename.replace(strip_ns(real_type.spelling), "win%s_%s" % (strip_ns(real_type.get_canonical().spelling), display_sdkver(sdkver)))
elif real_type.get_canonical().kind == clang.cindex.TypeKind.RECORD and \
strip_ns(real_type.spelling) in next_is_size_structs and \
struct_needs_size_adjustment(real_type.get_canonical()):
do_size_fixup = (strip_const(strip_ns(real_type.get_canonical().spelling)), param.spelling)
if param.spelling == "": if param.spelling == "":
cfile.write(", %s _%s" % (typename, unnamed)) cfile.write(", %s _%s" % (typename, unnamed))
@ -588,6 +594,7 @@ def handle_method(cfile, classname, winclassname, cppname, method, cpp, cpp_h, e
unnamed = 'a' unnamed = 'a'
first = True first = True
next_is_size = False next_is_size = False
next_is_size_no_conv = False
convert_size_param = "" convert_size_param = ""
for param in get_params(method): for param in get_params(method):
if not first: if not first:
@ -614,15 +621,24 @@ def handle_method(cfile, classname, winclassname, cppname, method, cpp, cpp_h, e
elif path_conv and param.spelling in path_conv["w2l_names"]: elif path_conv and param.spelling in path_conv["w2l_names"]:
cfile.write(", %s ? lin_%s : NULL" % (param.spelling, param.spelling)) cfile.write(", %s ? lin_%s : NULL" % (param.spelling, param.spelling))
cpp.write("(%s)%s" % (param.type.spelling, param.spelling)) cpp.write("(%s)%s" % (param.type.spelling, param.spelling))
elif do_size_fixup and do_size_fixup[1] == param.spelling:
next_is_size = True
next_is_size_no_conv = True
cfile.write(", %s" % param.spelling)
cpp.write("(%s)%s" % (param.type.spelling, param.spelling))
elif next_is_size: elif next_is_size:
cfile.write(", %s" % param.spelling) cfile.write(", %s" % param.spelling)
next_is_size = False next_is_size = False
if param.type.spelling == "uint32_t": if next_is_size_no_conv and param.type.spelling == "uint32_t":
cpp.write("std::min(%s, (uint32_t)sizeof(vr::%s))" % (param.spelling, do_size_fixup[0]))
convert_size_param = ", " + param.spelling
elif param.type.spelling == "uint32_t":
cpp.write("%s ? sizeof(lin) : 0" % param.spelling) cpp.write("%s ? sizeof(lin) : 0" % param.spelling)
convert_size_param = ", " + param.spelling convert_size_param = ", " + param.spelling
else: else:
cpp.write("(%s)%s" % (param.type.spelling, param.spelling)) cpp.write("(%s)%s" % (param.type.spelling, param.spelling))
convert_size_param = ", -1" convert_size_param = ", -1"
next_is_size_no_conv = False
elif "&" in param.type.spelling: elif "&" in param.type.spelling:
cfile.write(", %s" % param.spelling) cfile.write(", %s" % param.spelling)
cpp.write("*%s" % param.spelling) cpp.write("*%s" % param.spelling)
@ -884,15 +900,21 @@ def struct_needs_conversion_nocache(struct):
# if strip_const(struct.spelling) in manually_handled_structs: # if strip_const(struct.spelling) in manually_handled_structs:
# return True # return True
needs_size_adjustment = False
#check 32-bit compat #check 32-bit compat
windows_struct = find_windows_struct(struct) windows_struct = find_windows_struct(struct)
assert(not windows_struct is None) #must find windows_struct assert(not windows_struct is None) #must find windows_struct
for field in struct.get_fields(): for field in struct.get_fields():
if struct.get_offset(field.spelling) != windows_struct.get_offset(field.spelling): if struct.get_offset(field.spelling) != windows_struct.get_offset(field.spelling):
return True return True, False
if field.type.get_canonical().kind == clang.cindex.TypeKind.RECORD and \ if field.type.get_canonical().kind == clang.cindex.TypeKind.RECORD and \
struct_needs_conversion(field.type.get_canonical()): struct_needs_conversion(field.type.get_canonical()):
return True return True, False
assert(struct.get_size() <= windows_struct.get_size())
if struct.get_size() < windows_struct.get_size():
needs_size_adjustment = True
#check 64-bit compat #check 64-bit compat
windows_struct = find_windows64_struct(struct) windows_struct = find_windows64_struct(struct)
@ -901,20 +923,32 @@ def struct_needs_conversion_nocache(struct):
assert(not lin64_struct is None) #must find lin64_struct assert(not lin64_struct is None) #must find lin64_struct
for field in lin64_struct.get_fields(): for field in lin64_struct.get_fields():
if lin64_struct.get_offset(field.spelling) != windows_struct.get_offset(field.spelling): if lin64_struct.get_offset(field.spelling) != windows_struct.get_offset(field.spelling):
return True return True, False
if field.type.get_canonical().kind == clang.cindex.TypeKind.RECORD and \ if field.type.get_canonical().kind == clang.cindex.TypeKind.RECORD and \
struct_needs_conversion(field.type.get_canonical()): struct_needs_conversion(field.type.get_canonical()):
return True return True, False
return False assert(lin64_struct.get_size() <= windows_struct.get_size())
if lin64_struct.get_size() < windows_struct.get_size():
needs_size_adjustment = True
return False, needs_size_adjustment
def struct_needs_conversion(struct): def struct_needs_conversion(struct):
if not sdkver in struct_conversion_cache: if not sdkver in struct_conversion_cache:
struct_conversion_cache[sdkver] = {} struct_conversion_cache[sdkver] = {}
struct_needs_size_adjustment_cache[sdkver] = {}
if not strip_const(struct.spelling) in struct_conversion_cache[sdkver]: if not strip_const(struct.spelling) in struct_conversion_cache[sdkver]:
struct_conversion_cache[sdkver][strip_const(struct.spelling)] = struct_needs_conversion_nocache(struct) struct_conversion_cache[sdkver][strip_const(struct.spelling)], \
struct_needs_size_adjustment_cache[sdkver][strip_const(struct.spelling)] = \
struct_needs_conversion_nocache(struct)
return struct_conversion_cache[sdkver][strip_const(struct.spelling)] return struct_conversion_cache[sdkver][strip_const(struct.spelling)]
def struct_needs_size_adjustment(struct):
return not struct_needs_conversion(struct) and struct_needs_size_adjustment_cache[sdkver][strip_const(struct.spelling)]
def get_field_attribute_str(field): def get_field_attribute_str(field):
ftype = field.type.get_canonical() ftype = field.type.get_canonical()
if ftype.kind != clang.cindex.TypeKind.RECORD: if ftype.kind != clang.cindex.TypeKind.RECORD:

View File

@ -109,7 +109,7 @@ vr::EVRInputError cppIVRInput_IVRInput_003_GetOriginLocalizedName(void *linux_si
vr::EVRInputError cppIVRInput_IVRInput_003_GetOriginTrackedDeviceInfo(void *linux_side, VRInputValueHandle_t origin, InputOriginInfo_t * pOriginInfo, uint32_t unOriginInfoSize) vr::EVRInputError cppIVRInput_IVRInput_003_GetOriginTrackedDeviceInfo(void *linux_side, VRInputValueHandle_t origin, InputOriginInfo_t * pOriginInfo, uint32_t unOriginInfoSize)
{ {
return ((IVRInput*)linux_side)->GetOriginTrackedDeviceInfo((vr::VRInputValueHandle_t)origin, (vr::InputOriginInfo_t *)pOriginInfo, (uint32_t)unOriginInfoSize); return ((IVRInput*)linux_side)->GetOriginTrackedDeviceInfo((vr::VRInputValueHandle_t)origin, (vr::InputOriginInfo_t *)pOriginInfo, std::min(unOriginInfoSize, (uint32_t)sizeof(vr::InputOriginInfo_t)));
} }
vr::EVRInputError cppIVRInput_IVRInput_003_ShowActionOrigins(void *linux_side, VRActionSetHandle_t actionSetHandle, VRActionHandle_t ulActionHandle) vr::EVRInputError cppIVRInput_IVRInput_003_ShowActionOrigins(void *linux_side, VRActionSetHandle_t actionSetHandle, VRActionHandle_t ulActionHandle)

View File

@ -114,7 +114,7 @@ vr::EVRInputError cppIVRInput_IVRInput_004_GetOriginLocalizedName(void *linux_si
vr::EVRInputError cppIVRInput_IVRInput_004_GetOriginTrackedDeviceInfo(void *linux_side, VRInputValueHandle_t origin, InputOriginInfo_t * pOriginInfo, uint32_t unOriginInfoSize) vr::EVRInputError cppIVRInput_IVRInput_004_GetOriginTrackedDeviceInfo(void *linux_side, VRInputValueHandle_t origin, InputOriginInfo_t * pOriginInfo, uint32_t unOriginInfoSize)
{ {
return ((IVRInput*)linux_side)->GetOriginTrackedDeviceInfo((vr::VRInputValueHandle_t)origin, (vr::InputOriginInfo_t *)pOriginInfo, (uint32_t)unOriginInfoSize); return ((IVRInput*)linux_side)->GetOriginTrackedDeviceInfo((vr::VRInputValueHandle_t)origin, (vr::InputOriginInfo_t *)pOriginInfo, std::min(unOriginInfoSize, (uint32_t)sizeof(vr::InputOriginInfo_t)));
} }
vr::EVRInputError cppIVRInput_IVRInput_004_ShowActionOrigins(void *linux_side, VRActionSetHandle_t actionSetHandle, VRActionHandle_t ulActionHandle) vr::EVRInputError cppIVRInput_IVRInput_004_ShowActionOrigins(void *linux_side, VRActionSetHandle_t actionSetHandle, VRActionHandle_t ulActionHandle)

View File

@ -144,7 +144,7 @@ vr::EVRInputError cppIVRInput_IVRInput_005_GetOriginLocalizedName(void *linux_si
vr::EVRInputError cppIVRInput_IVRInput_005_GetOriginTrackedDeviceInfo(void *linux_side, VRInputValueHandle_t origin, InputOriginInfo_t * pOriginInfo, uint32_t unOriginInfoSize) vr::EVRInputError cppIVRInput_IVRInput_005_GetOriginTrackedDeviceInfo(void *linux_side, VRInputValueHandle_t origin, InputOriginInfo_t * pOriginInfo, uint32_t unOriginInfoSize)
{ {
return ((IVRInput*)linux_side)->GetOriginTrackedDeviceInfo((vr::VRInputValueHandle_t)origin, (vr::InputOriginInfo_t *)pOriginInfo, (uint32_t)unOriginInfoSize); return ((IVRInput*)linux_side)->GetOriginTrackedDeviceInfo((vr::VRInputValueHandle_t)origin, (vr::InputOriginInfo_t *)pOriginInfo, std::min(unOriginInfoSize, (uint32_t)sizeof(vr::InputOriginInfo_t)));
} }
vr::EVRInputError cppIVRInput_IVRInput_005_ShowActionOrigins(void *linux_side, VRActionSetHandle_t actionSetHandle, VRActionHandle_t ulActionHandle) vr::EVRInputError cppIVRInput_IVRInput_005_ShowActionOrigins(void *linux_side, VRActionSetHandle_t actionSetHandle, VRActionHandle_t ulActionHandle)

View File

@ -156,7 +156,7 @@ vr::EVRInputError cppIVRInput_IVRInput_006_GetOriginLocalizedName(void *linux_si
vr::EVRInputError cppIVRInput_IVRInput_006_GetOriginTrackedDeviceInfo(void *linux_side, VRInputValueHandle_t origin, InputOriginInfo_t * pOriginInfo, uint32_t unOriginInfoSize) vr::EVRInputError cppIVRInput_IVRInput_006_GetOriginTrackedDeviceInfo(void *linux_side, VRInputValueHandle_t origin, InputOriginInfo_t * pOriginInfo, uint32_t unOriginInfoSize)
{ {
return ((IVRInput*)linux_side)->GetOriginTrackedDeviceInfo((vr::VRInputValueHandle_t)origin, (vr::InputOriginInfo_t *)pOriginInfo, (uint32_t)unOriginInfoSize); return ((IVRInput*)linux_side)->GetOriginTrackedDeviceInfo((vr::VRInputValueHandle_t)origin, (vr::InputOriginInfo_t *)pOriginInfo, std::min(unOriginInfoSize, (uint32_t)sizeof(vr::InputOriginInfo_t)));
} }
vr::EVRInputError cppIVRInput_IVRInput_006_ShowActionOrigins(void *linux_side, VRActionSetHandle_t actionSetHandle, VRActionHandle_t ulActionHandle) vr::EVRInputError cppIVRInput_IVRInput_006_ShowActionOrigins(void *linux_side, VRActionSetHandle_t actionSetHandle, VRActionHandle_t ulActionHandle)

View File

@ -156,7 +156,7 @@ vr::EVRInputError cppIVRInput_IVRInput_007_GetOriginLocalizedName(void *linux_si
vr::EVRInputError cppIVRInput_IVRInput_007_GetOriginTrackedDeviceInfo(void *linux_side, VRInputValueHandle_t origin, InputOriginInfo_t * pOriginInfo, uint32_t unOriginInfoSize) vr::EVRInputError cppIVRInput_IVRInput_007_GetOriginTrackedDeviceInfo(void *linux_side, VRInputValueHandle_t origin, InputOriginInfo_t * pOriginInfo, uint32_t unOriginInfoSize)
{ {
return ((IVRInput*)linux_side)->GetOriginTrackedDeviceInfo((vr::VRInputValueHandle_t)origin, (vr::InputOriginInfo_t *)pOriginInfo, (uint32_t)unOriginInfoSize); return ((IVRInput*)linux_side)->GetOriginTrackedDeviceInfo((vr::VRInputValueHandle_t)origin, (vr::InputOriginInfo_t *)pOriginInfo, std::min(unOriginInfoSize, (uint32_t)sizeof(vr::InputOriginInfo_t)));
} }
vr::EVRInputError cppIVRInput_IVRInput_007_GetActionBindingInfo(void *linux_side, VRActionHandle_t action, InputBindingInfo_t * pOriginInfo, uint32_t unBindingInfoSize, uint32_t unBindingInfoCount, uint32_t * punReturnedBindingInfoCount) vr::EVRInputError cppIVRInput_IVRInput_007_GetActionBindingInfo(void *linux_side, VRActionHandle_t action, InputBindingInfo_t * pOriginInfo, uint32_t unBindingInfoSize, uint32_t unBindingInfoCount, uint32_t * punReturnedBindingInfoCount)

View File

@ -166,7 +166,7 @@ vr::EVRInputError cppIVRInput_IVRInput_010_GetOriginLocalizedName(void *linux_si
vr::EVRInputError cppIVRInput_IVRInput_010_GetOriginTrackedDeviceInfo(void *linux_side, VRInputValueHandle_t origin, InputOriginInfo_t * pOriginInfo, uint32_t unOriginInfoSize) vr::EVRInputError cppIVRInput_IVRInput_010_GetOriginTrackedDeviceInfo(void *linux_side, VRInputValueHandle_t origin, InputOriginInfo_t * pOriginInfo, uint32_t unOriginInfoSize)
{ {
return ((IVRInput*)linux_side)->GetOriginTrackedDeviceInfo((vr::VRInputValueHandle_t)origin, (vr::InputOriginInfo_t *)pOriginInfo, (uint32_t)unOriginInfoSize); return ((IVRInput*)linux_side)->GetOriginTrackedDeviceInfo((vr::VRInputValueHandle_t)origin, (vr::InputOriginInfo_t *)pOriginInfo, std::min(unOriginInfoSize, (uint32_t)sizeof(vr::InputOriginInfo_t)));
} }
vr::EVRInputError cppIVRInput_IVRInput_010_GetActionBindingInfo(void *linux_side, VRActionHandle_t action, InputBindingInfo_t * pOriginInfo, uint32_t unBindingInfoSize, uint32_t unBindingInfoCount, uint32_t * punReturnedBindingInfoCount) vr::EVRInputError cppIVRInput_IVRInput_010_GetActionBindingInfo(void *linux_side, VRActionHandle_t action, InputBindingInfo_t * pOriginInfo, uint32_t unBindingInfoSize, uint32_t unBindingInfoCount, uint32_t * punReturnedBindingInfoCount)

View File

@ -1,4 +1,6 @@
#ifndef __cplusplus #ifdef __cplusplus
#include <algorithm>
#else
#ifndef bool #ifndef bool
typedef char bool; /* 1 byte on modern visual studio c++ */ typedef char bool; /* 1 byte on modern visual studio c++ */
#endif #endif