gfxstream: cereal: fix 'None' in gfxstream codegen
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Commit e27e41a842 ("vulkan,spirv: update headers") exposed a
flaw in the cerealgenerator.

It modified -- among other things -- the VkDeviceCreateInfo
struct in vk.xml.

In the update, the len="enabledLayerCount,null-terminated"
attribute was removed from the ppEnabledLayerNames member.

The gfxstream code generator processes ppEnabledLayerNames
(which is a const char* const*), it identifies it as an "array of
strings". However, because the len attribute is now missing,
vulkanType.getLengthExpression() returns None.

This leads to errors like:

gfxstream_guest_vk_autogen_impl/gen/goldfish_vk_counting_guest.cpp:642:30:
error: use of undeclared identifier 'None'

     642 |     for (uint32_t i = 0; i < None; ++i)
         |                              ^~~~
   1 error generated.

This patch adds various length access checks to prevent this from
happening.

TEST=m vulkan.ranchu

Reviewed-by: David Gilhooley <djgilhooley@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40785>
This commit is contained in:
Gurchetan Singh 2026-04-02 16:45:50 -07:00
parent 77835f6c21
commit c4cecd9d19
6 changed files with 87 additions and 75 deletions

View file

@ -370,25 +370,27 @@ class VulkanCountingCodegen(VulkanTypeIterator):
lenAccessGuard = self.lenAccessorGuard(vulkanType)
self.genCount("sizeof(uint32_t)")
if lenAccessGuard is not None:
self.cgen.beginIf(lenAccessGuard)
self.cgen.beginFor("uint32_t i = 0", "i < %s" % lenAccess, "++i")
self.genCount("sizeof(uint32_t) + (%s[i] ? strlen(%s[i]) : 0)" % (access, access))
self.cgen.endFor()
if lenAccessGuard is not None:
self.cgen.endIf()
if lenAccess is not None:
if lenAccessGuard is not None:
self.cgen.beginIf(lenAccessGuard)
self.cgen.beginFor("uint32_t i = 0", "i < %s" % lenAccess, "++i")
self.genCount("sizeof(uint32_t) + (%s[i] ? strlen(%s[i]) : 0)" % (access, access))
self.cgen.endFor()
if lenAccessGuard is not None:
self.cgen.endIf()
def onStaticArr(self, vulkanType):
access = self.exprValueAccessor(vulkanType)
lenAccess = self.lenAccessor(vulkanType)
lenAccessGuard = self.lenAccessorGuard(vulkanType)
if lenAccessGuard is not None:
self.cgen.beginIf(lenAccessGuard)
finalLenExpr = "%s * %s" % (lenAccess, self.cgen.sizeofExpr(vulkanType))
if lenAccessGuard is not None:
self.cgen.endIf()
self.genCount(finalLenExpr)
if lenAccess is not None:
if lenAccessGuard is not None:
self.cgen.beginIf(lenAccessGuard)
finalLenExpr = "%s * %s" % (lenAccess, self.cgen.sizeofExpr(vulkanType))
if lenAccessGuard is not None:
self.cgen.endIf()
self.genCount(finalLenExpr)
def onStructExtension(self, vulkanType):
sTypeParam = copy(vulkanType)

View file

@ -155,16 +155,17 @@ class DeepcopyCodegen(VulkanTypeIterator):
lenAccessLhs = self.lenAccessorLhs(vulkanType)
self.cgen.stmt("%s = nullptr" % accessRhs)
self.cgen.beginIf("%s && %s" % (accessLhs, lenAccessLhs))
if lenAccessLhs is not None:
self.cgen.beginIf("%s && %s" % (accessLhs, lenAccessLhs))
self.cgen.stmt( \
"%s = %s->strDupArray(%s, %s)" % \
(accessRhs,
self.poolVarName,
accessLhs,
lenAccessLhs))
self.cgen.stmt( \
"%s = %s->strDupArray(%s, %s)" % \
(accessRhs,
self.poolVarName,
accessLhs,
lenAccessLhs))
self.cgen.endIf()
self.cgen.endIf()
def onStaticArr(self, vulkanType):
accessLhs = self.exprAccessorValueLhs(vulkanType)

View file

@ -108,10 +108,11 @@ class HandleMapCodegen(VulkanTypeIterator):
accessLhs = self.exprAccessor(vulkanType)
lenAccess = self.lenAccessor(vulkanType)
self.cgen.stmt("%s->mapHandles_%s(%s%s, %s)" % \
(self.handlemapVarName, vulkanType.typeName,
self.makeCastExpr(vulkanType.getForAddressAccess().getForNonConstAccess()),
accessLhs, lenAccess))
if lenAccess is not None:
self.cgen.stmt("%s->mapHandles_%s(%s%s, %s)" % \
(self.handlemapVarName, vulkanType.typeName,
self.makeCastExpr(vulkanType.getForAddressAccess().getForNonConstAccess()),
accessLhs, lenAccess))
def onStructExtension(self, vulkanType):
access = self.exprAccessor(vulkanType)

View file

@ -455,8 +455,9 @@ class VulkanMarshalingCodegen(VulkanTypeIterator):
lenAccess = self.lenAccessor(vulkanType)
if self.direction == "write":
self.cgen.stmt("saveStringArray(%s, %s, %s)" % (self.streamVarName,
access, lenAccess))
if lenAccess is not None:
self.cgen.stmt("saveStringArray(%s, %s, %s)" % (self.streamVarName,
access, lenAccess))
else:
castExpr = \
self.makeCastExpr( \
@ -468,7 +469,10 @@ class VulkanMarshalingCodegen(VulkanTypeIterator):
def onStaticArr(self, vulkanType):
access = self.exprValueAccessor(vulkanType)
lenAccess = self.lenAccessor(vulkanType)
finalLenExpr = "%s * %s" % (lenAccess, self.cgen.sizeofExpr(vulkanType))
if lenAccess is not None:
finalLenExpr = "%s * %s" % (lenAccess, self.cgen.sizeofExpr(vulkanType))
else:
finalLenExpr = self.cgen.sizeofExpr(vulkanType)
self.genStreamCall(vulkanType, access, finalLenExpr)
# Old version VkEncoder may have some sType values conflict with VkDecoder

View file

@ -548,25 +548,26 @@ class VulkanReservedMarshalingCodegen(VulkanTypeIterator):
lenAccessGuard = self.lenAccessorGuard(vulkanType)
if self.direction == "write":
self.cgen.beginBlock()
if lenAccess is not None:
self.cgen.beginBlock()
self.cgen.stmt("uint32_t c = 0")
if lenAccessGuard is not None:
self.cgen.beginIf(lenAccessGuard)
self.cgen.stmt("c = %s" % (lenAccess))
if lenAccessGuard is not None:
self.cgen.stmt("uint32_t c = 0")
if lenAccessGuard is not None:
self.cgen.beginIf(lenAccessGuard)
self.cgen.stmt("c = %s" % (lenAccess))
if lenAccessGuard is not None:
self.cgen.endIf()
self.genMemcpyAndIncr(self.ptrVar, "(uint32_t*)" ,"&c", "sizeof(uint32_t)", toBe = True, actualSize = 4)
self.cgen.beginFor("uint32_t i = 0", "i < c", "++i")
self.cgen.stmt("uint32_t l = %s ? strlen(%s[i]): 0" % (access, access))
self.genMemcpyAndIncr(self.ptrVar, "(uint32_t*)" ,"&l", "sizeof(uint32_t)", toBe = True, actualSize = 4)
self.cgen.beginIf("l")
self.genMemcpyAndIncr(self.ptrVar, "(char*)", "(%s[i])" % access, "l")
self.cgen.endIf()
self.genMemcpyAndIncr(self.ptrVar, "(uint32_t*)" ,"&c", "sizeof(uint32_t)", toBe = True, actualSize = 4)
self.cgen.endFor()
self.cgen.beginFor("uint32_t i = 0", "i < c", "++i")
self.cgen.stmt("uint32_t l = %s ? strlen(%s[i]): 0" % (access, access))
self.genMemcpyAndIncr(self.ptrVar, "(uint32_t*)" ,"&l", "sizeof(uint32_t)", toBe = True, actualSize = 4)
self.cgen.beginIf("l")
self.genMemcpyAndIncr(self.ptrVar, "(char*)", "(%s[i])" % access, "l")
self.cgen.endIf()
self.cgen.endFor()
self.cgen.endBlock()
self.cgen.endBlock()
else:
castExpr = \
self.makeCastExpr( \
@ -578,8 +579,9 @@ class VulkanReservedMarshalingCodegen(VulkanTypeIterator):
def onStaticArr(self, vulkanType):
access = self.exprValueAccessor(vulkanType)
lenAccess = self.lenAccessor(vulkanType)
finalLenExpr = "%s * %s" % (lenAccess, self.cgen.sizeofExpr(vulkanType))
self.genStreamCall(vulkanType, access, finalLenExpr)
if lenAccess is not None:
finalLenExpr = "%s * %s" % (lenAccess, self.cgen.sizeofExpr(vulkanType))
self.genStreamCall(vulkanType, access, finalLenExpr)
# Old version VkEncoder may have some sType values conflict with VkDecoder
# of new versions. For host decoder, it should not carry the incorrect old

View file

@ -205,53 +205,55 @@ class VulkanEqualityCodegen(VulkanTypeIterator):
vulkanType,
"Mismatch in string array pointer nullness")
equalLenExpr = self.makeEqualExpr(lenAccessLhs, lenAccessRhs)
if lenAccessLhs is not None and lenAccessRhs is not None:
equalLenExpr = self.makeEqualExpr(lenAccessLhs, lenAccessRhs)
self.compareWithConsequence( \
equalLenExpr,
vulkanType, "Lengths not equal in string array")
self.compareWithConsequence( \
equalLenExpr,
vulkanType, "Lengths not equal in string array")
self.compareWithConsequence( \
equalLenExpr,
vulkanType, "Lengths not equal in string array")
self.compareWithConsequence( \
equalLenExpr,
vulkanType, "Lengths not equal in string array")
self.cgen.beginIf("%s && %s" % (equalLenExpr, bothNotNullExpr))
self.cgen.beginIf("%s && %s" % (equalLenExpr, bothNotNullExpr))
loopVar = "i"
accessLhs = "*(%s + %s)" % (accessLhs, loopVar)
accessRhs = "*(%s + %s)" % (accessRhs, loopVar)
forInit = "uint32_t %s = 0" % loopVar
forCond = "%s < (uint32_t)%s" % (loopVar, lenAccessLhs)
forIncr = "++%s" % loopVar
loopVar = "i"
accessLhs = "*(%s + %s)" % (accessLhs, loopVar)
accessRhs = "*(%s + %s)" % (accessRhs, loopVar)
forInit = "uint32_t %s = 0" % loopVar
forCond = "%s < (uint32_t)%s" % (loopVar, lenAccessLhs)
forIncr = "++%s" % loopVar
if lenAccessGuardLhs is not None:
self.cgen.beginIf(lenAccessGuardLhs)
if lenAccessGuardLhs is not None:
self.cgen.beginIf(lenAccessGuardLhs)
self.cgen.beginFor(forInit, forCond, forIncr)
self.cgen.beginFor(forInit, forCond, forIncr)
self.compareWithConsequence(
self.makeEqualStringExpr(accessLhs, accessRhs),
vulkanType, "Unequal string in string array")
self.compareWithConsequence(
self.makeEqualStringExpr(accessLhs, accessRhs),
vulkanType, "Unequal string in string array")
self.cgen.endFor()
self.cgen.endFor()
if lenAccessGuardLhs is not None:
self.cgen.endIf()
if lenAccessGuardLhs is not None:
self.cgen.endIf()
self.cgen.endIf()
def onStaticArr(self, vulkanType):
accessLhs = self.exprAccessorLhs(vulkanType)
accessRhs = self.exprAccessorRhs(vulkanType)
lenAccessLhs = self.lenAccessorLhs(vulkanType)
finalLenExpr = "%s * %s" % (lenAccessLhs,
self.cgen.sizeofExpr(vulkanType))
if lenAccessLhs is not None:
finalLenExpr = "%s * %s" % (lenAccessLhs,
self.cgen.sizeofExpr(vulkanType))
self.compareWithConsequence(
self.makeEqualBufExpr(accessLhs, accessRhs, finalLenExpr),
vulkanType, "Unequal static array")
self.compareWithConsequence(
self.makeEqualBufExpr(accessLhs, accessRhs, finalLenExpr),
vulkanType, "Unequal static array")
def onStructExtension(self, vulkanType):
lhs = self.exprAccessorLhs(vulkanType)