gallium/swr: Fix various asserts and security issues

To improve the robustness of the code, we want to better
detect issues in testing (using asserts) and use more
secure techniques.

Reviewed-by: Krzysztof Raszkowski <krzysztof.raszkowski@intel.com>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3710>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3710>
This commit is contained in:
Jan Zielinski
2020-02-05 13:57:55 +01:00
committed by Marge Bot
parent 7eaf21cb6f
commit 23c137612b
14 changed files with 52 additions and 30 deletions
+2 -1
View File
@@ -450,7 +450,7 @@ lp_build_init(void)
*/
lp_native_vector_width = 128;
}
lp_native_vector_width = debug_get_num_option("LP_NATIVE_VECTOR_WIDTH",
lp_native_vector_width);
@@ -513,6 +513,7 @@ gallivm_create(const char *name, LLVMContextRef context)
}
}
assert(gallivm != NULL);
return gallivm;
}
@@ -103,9 +103,10 @@ void BucketManager::PrintBucket(
BUCKET_DESC& desc = mBuckets[bucket.id];
// construct hierarchy visualization
std::string str = arrows[level];
str += desc.name;
char hier[80];
strcpy(hier, arrows[level]);
strcat(hier, desc.name.c_str());
strcpy_s(hier, sizeof(hier), str.c_str());
// print out
fprintf(f,
@@ -156,6 +157,7 @@ void BucketManager::PrintReport(const std::string& filename)
{
{
FILE* f = fopen(filename.c_str(), "w");
assert(f);
mThreadMutex.lock();
for (const BUCKET_THREAD& thread : mThreads)
@@ -164,12 +164,6 @@ void SwrTrace(
#define SWR_ASSERT(e, ...) _SWR_ASSERT(true, e, ##__VA_ARGS__)
#define SWR_ASSUME_ASSERT(e, ...) SWR_ASSERT(e, ##__VA_ARGS__)
#define SWR_TRACE(_fmtstr, ...) _SWR_TRACE(_fmtstr, ##__VA_ARGS__)
#if defined(assert)
#undef assert
#endif
#define assert(exp) SWR_ASSERT(exp)
#endif // SWR_ENABLE_ASSERTS
#if SWR_ENABLE_REL_ASSERTS
@@ -478,7 +478,7 @@ void SWR_API SwrSaveState(HANDLE hContext, void* pOutputStateBlock, size_t memSi
{
SWR_CONTEXT* pContext = GetContext(hContext);
auto pSrc = GetDrawState(pContext);
SWR_ASSERT(pOutputStateBlock && memSize >= sizeof(*pSrc));
assert(pOutputStateBlock && memSize >= sizeof(*pSrc));
memcpy(pOutputStateBlock, pSrc, sizeof(*pSrc));
}
@@ -487,7 +487,7 @@ void SWR_API SwrRestoreState(HANDLE hContext, const void* pStateBlock, size_t me
{
SWR_CONTEXT* pContext = GetContext(hContext);
auto pDst = GetDrawState(pContext);
SWR_ASSERT(pStateBlock && memSize >= sizeof(*pDst));
assert(pStateBlock && memSize >= sizeof(*pDst));
memcpy(pDst, pStateBlock, sizeof(*pDst));
}
@@ -110,7 +110,7 @@ struct CachingAllocatorT : DefaultAllocator
if (pBlock)
{
SWR_ASSUME_ASSERT(pPrevBlock && pPrevBlock->pNext == pBlock);
assert(pPrevBlock && pPrevBlock->pNext == pBlock);
pPrevBlock->pNext = pBlock->pNext;
pBlock->pNext = nullptr;
@@ -113,6 +113,7 @@ namespace Tessellator
default:
SWR_INVALID("Invalid Tessellation Domain: %d", Domain);
assert(false);
}
NumDomainPoints = (uint32_t)SUPER::GetPointCount();
@@ -1006,6 +1006,7 @@ void CreateThreadPool(SWR_CONTEXT* pContext, THREAD_POOL* pPool)
CPUNumaNodes nodes;
uint32_t numThreadsPerProcGroup = 0;
CalculateProcessorTopology(nodes, numThreadsPerProcGroup);
assert(numThreadsPerProcGroup > 0);
// Assumption, for asymmetric topologies, multi-threaded cores will appear
// in the list before single-threaded cores. This appears to be true for
@@ -1191,7 +1192,7 @@ void CreateThreadPool(SWR_CONTEXT* pContext, THREAD_POOL* pPool)
pContext->NumWorkerThreads = pPool->numThreads;
pPool->pThreadData = new (std::nothrow) THREAD_DATA[pPool->numThreads];
SWR_ASSERT(pPool->pThreadData);
assert(pPool->pThreadData);
memset(pPool->pThreadData, 0, sizeof(THREAD_DATA) * pPool->numThreads);
pPool->numaMask = 0;
@@ -1203,7 +1204,7 @@ void CreateThreadPool(SWR_CONTEXT* pContext, THREAD_POOL* pPool)
pContext->workerPrivateState.pfnInitWorkerData = nullptr;
pContext->workerPrivateState.pfnFinishWorkerData = nullptr;
}
// initialize contents of SWR_WORKER_DATA
size_t perWorkerSize =
AlignUpPow2(pContext->workerPrivateState.perWorkerPrivateStateSize, 64);
@@ -1231,7 +1232,7 @@ void CreateThreadPool(SWR_CONTEXT* pContext, THREAD_POOL* pPool)
}
pPool->pThreads = new (std::nothrow) THREAD_PTR[pPool->numThreads];
SWR_ASSERT(pPool->pThreads);
assert(pPool->pThreads);
if (pContext->threadInfo.MAX_WORKER_THREADS)
{
@@ -1300,7 +1301,7 @@ void CreateThreadPool(SWR_CONTEXT* pContext, THREAD_POOL* pPool)
if (numRemovedThreads)
{
--numRemovedThreads;
SWR_REL_ASSERT(numReservedThreads);
assert(numReservedThreads);
--numReservedThreads;
pPool->pApiThreadData[numReservedThreads].workerId = 0xFFFFFFFFU;
pPool->pApiThreadData[numReservedThreads].procGroupId = core.procGroup;
@@ -632,6 +632,7 @@ namespace SwrJit
break;
}
assert(vConstMask && "Invalid info.numComps value");
vGatherOutput[swizzleIndex] =
BITCAST(PSHUFB(BITCAST(vGatherInput, v32x8Ty), vConstMask), vGatherTy);
// after pshufb for x channel
@@ -654,7 +655,7 @@ namespace SwrJit
// if (vSrc->getType() != mSimdFP32Ty)
// {
// vSrc = BITCAST(vSrc, mSimdFP32Ty);
// }
// }
SWR_ASSERT(vSrc->getType()->getVectorElementType()->isFloatTy());
VSCATTERPS(pDst, vMask, vOffsets, vSrc, C(1));
return;
@@ -553,6 +553,7 @@ namespace SwrJit
else
{
Constant* cB = dyn_cast<Constant>(b);
assert(cB != nullptr);
// number of 8 bit elements in b
uint32_t numElms = cast<VectorType>(cB->getType())->getNumElements();
// output vector
@@ -209,8 +209,8 @@ Function* FetchJit::Create(const FETCH_COMPILE_STATE& fetchState)
: vIndices = GetSimdValid32bitIndices(indices, pLastIndex);
break; // incoming type is already 32bit int
default:
SWR_INVALID("Unsupported index type");
vIndices = nullptr;
assert(false && "Unsupported index type");
break;
}
@@ -1392,11 +1392,11 @@ void FetchJit::Shuffle8bpcGatherd16(Shuffle8bpcArgs& args)
conversionFactor = VIMMED1((float)(1.0));
break;
case CONVERT_USCALED:
SWR_INVALID("Type should not be sign extended!");
assert(false && "Type should not be sign extended!");
conversionFactor = nullptr;
break;
default:
SWR_ASSERT(conversionType == CONVERT_NONE);
assert(conversionType == CONVERT_NONE);
conversionFactor = nullptr;
break;
}
@@ -1466,11 +1466,11 @@ void FetchJit::Shuffle8bpcGatherd16(Shuffle8bpcArgs& args)
conversionFactor = VIMMED1((float)(1.0));
break;
case CONVERT_SSCALED:
SWR_INVALID("Type should not be zero extended!");
assert(false && "Type should not be zero extended!");
conversionFactor = nullptr;
break;
default:
SWR_ASSERT(conversionType == CONVERT_NONE);
assert(conversionType == CONVERT_NONE);
conversionFactor = nullptr;
break;
}
@@ -1511,6 +1511,7 @@ void FetchJit::Shuffle8bpcGatherd16(Shuffle8bpcArgs& args)
3, -1, -1, -1, 7, -1, -1, -1, 11, -1, -1, -1, 15, -1, -1, -1});
break;
default:
assert(false && "Invalid component");
vConstMask = nullptr;
break;
}
@@ -1762,11 +1763,11 @@ void FetchJit::Shuffle16bpcGather16(Shuffle16bpcArgs& args)
conversionFactor = VIMMED1((float)(1.0));
break;
case CONVERT_USCALED:
SWR_INVALID("Type should not be sign extended!");
assert(false && "Type should not be sign extended!");
conversionFactor = nullptr;
break;
default:
SWR_ASSERT(conversionType == CONVERT_NONE);
assert(conversionType == CONVERT_NONE);
conversionFactor = nullptr;
break;
}
@@ -224,13 +224,16 @@ namespace SwrJit
TargetWidth* pWidth,
Type** pTy)
{
assert(pCallInst);
Type* pVecTy = pCallInst->getType();
// Check for intrinsic specific types
// VCVTPD2PS type comes from src, not dst
if (intrinName.equals("meta.intrinsic.VCVTPD2PS"))
{
pVecTy = pCallInst->getOperand(0)->getType();
Value* pOp = pCallInst->getOperand(0);
assert(pOp);
pVecTy = pOp->getType();
}
if (!pVecTy->isVectorTy())
@@ -307,7 +310,9 @@ namespace SwrJit
Instruction* ProcessIntrinsicAdvanced(CallInst* pCallInst)
{
Function* pFunc = pCallInst->getCalledFunction();
Function* pFunc = pCallInst->getCalledFunction();
assert(pFunc);
auto& intrinsic = intrinsicMap2[mTarget][pFunc->getName()];
TargetWidth vecWidth;
Type* pElemTy;
@@ -367,6 +372,7 @@ namespace SwrJit
Instruction* ProcessIntrinsic(CallInst* pCallInst)
{
Function* pFunc = pCallInst->getCalledFunction();
assert(pFunc);
// Forward to the advanced support if found
if (intrinsicMap2[mTarget].find(pFunc->getName()) != intrinsicMap2[mTarget].end())
@@ -731,7 +737,9 @@ namespace SwrJit
auto B = pThis->B;
auto vf32Src = pCallInst->getOperand(0);
assert(vf32Src);
auto i8Round = pCallInst->getOperand(1);
assert(i8Round);
auto pfnFunc =
Intrinsic::getDeclaration(B->JM()->mpCurrentModule, Intrinsic::x86_avx_round_ps_256);
+1 -1
View File
@@ -46,9 +46,9 @@ swr_create_query(struct pipe_context *pipe, unsigned type, unsigned index)
assert(index < MAX_SO_STREAMS);
pq = (struct swr_query *) AlignedMalloc(sizeof(struct swr_query), 64);
memset(pq, 0, sizeof(*pq));
if (pq) {
memset(pq, 0, sizeof(*pq));
pq->type = type;
pq->index = index;
}
+14 -3
View File
@@ -1510,6 +1510,7 @@ BuilderSWR::CompileGS(struct swr_context *ctx, swr_jit_gs_key &key)
struct lp_build_sampler_soa *sampler =
swr_sampler_soa_create(key.sampler, PIPE_SHADER_GEOMETRY);
assert(sampler != nullptr);
struct lp_bld_tgsi_system_values system_values;
memset(&system_values, 0, sizeof(system_values));
@@ -1523,6 +1524,7 @@ BuilderSWR::CompileGS(struct swr_context *ctx, swr_jit_gs_key &key)
ubyte semantic_idx = info->input_semantic_index[slot];
unsigned vs_slot = locate_linkage(semantic_name, semantic_idx, &ctx->vs->info.base);
assert(vs_slot < PIPE_MAX_SHADER_OUTPUTS);
vs_slot += VERTEX_ATTRIB_START_SLOT;
@@ -1736,6 +1738,7 @@ BuilderSWR::CompileTES(struct swr_context *ctx, swr_jit_tes_key &key)
struct lp_build_sampler_soa *sampler =
swr_sampler_soa_create(key.sampler, PIPE_SHADER_TESS_EVAL);
assert(sampler != nullptr);
struct lp_bld_tgsi_system_values system_values;
memset(&system_values, 0, sizeof(system_values));
@@ -1830,6 +1833,7 @@ BuilderSWR::CompileTES(struct swr_context *ctx, swr_jit_tes_key &key)
// Where in TCS output is my attribute?
// TESS_TODO: revisit after implement pass-through TCS
unsigned tcs_slot = locate_linkage(semantic_name, semantic_idx, pPrevShader);
assert(tcs_slot < PIPE_MAX_SHADER_OUTPUTS);
// Skip tessellation levels - these go to the tessellator, not TES
switch (semantic_name) {
@@ -2035,6 +2039,7 @@ BuilderSWR::CompileTCS(struct swr_context *ctx, swr_jit_tcs_key &key)
struct lp_build_sampler_soa *sampler =
swr_sampler_soa_create(key.sampler, PIPE_SHADER_TESS_CTRL);
assert(sampler != nullptr);
struct lp_bld_tgsi_system_values system_values;
memset(&system_values, 0, sizeof(system_values));
@@ -2069,6 +2074,7 @@ BuilderSWR::CompileTCS(struct swr_context *ctx, swr_jit_tcs_key &key)
unsigned vs_slot =
locate_linkage(semantic_name, semantic_idx, &ctx->vs->info.base);
assert(vs_slot < PIPE_MAX_SHADER_OUTPUTS);
vs_slot += VERTEX_ATTRIB_START_SLOT;
@@ -2311,6 +2317,7 @@ BuilderSWR::CompileVS(struct swr_context *ctx, swr_jit_vs_key &key)
struct lp_build_sampler_soa *sampler =
swr_sampler_soa_create(key.sampler, PIPE_SHADER_VERTEX);
assert(sampler != nullptr);
struct lp_bld_tgsi_system_values system_values;
memset(&system_values, 0, sizeof(system_values));
@@ -2397,6 +2404,7 @@ BuilderSWR::CompileVS(struct swr_context *ctx, swr_jit_vs_key &key)
}
}
}
assert(cv < PIPE_MAX_SHADER_OUTPUTS);
LLVMValueRef cx = LLVMBuildLoad(gallivm->builder, outputs[cv][0], "");
LLVMValueRef cy = LLVMBuildLoad(gallivm->builder, outputs[cv][1], "");
LLVMValueRef cz = LLVMBuildLoad(gallivm->builder, outputs[cv][2], "");
@@ -2419,6 +2427,7 @@ BuilderSWR::CompileVS(struct swr_context *ctx, swr_jit_vs_key &key)
if ((pLastFE->clipdist_writemask & clip_mask & (1 << val)) ||
((pLastFE->culldist_writemask << pLastFE->num_written_clipdistance) & (1 << val))) {
unsigned cv = locate_linkage(TGSI_SEMANTIC_CLIPDIST, val < 4 ? 0 : 1, pLastFE);
assert(cv < PIPE_MAX_SHADER_OUTPUTS);
if (val < 4) {
LLVMValueRef dist = LLVMBuildLoad(gallivm->builder, outputs[cv][val], "");
WriteVS(unwrap(dist), pVsCtx, vtxOutput, VERTEX_CLIPCULL_DIST_LO_SLOT, val);
@@ -2711,7 +2720,7 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key)
linkedAttrib = pPrevShader->num_outputs + extraAttribs - 1;
swr_fs->pointSpriteMask |= (1 << linkedAttrib);
extraAttribs++;
} else if (linkedAttrib == 0xFFFFFFFF) {
} else if (linkedAttrib + 1 == 0xFFFFFFFF) {
inputs[attrib][0] = wrap(VIMMED1(0.0f));
inputs[attrib][1] = wrap(VIMMED1(0.0f));
inputs[attrib][2] = wrap(VIMMED1(0.0f));
@@ -2733,15 +2742,16 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key)
Value *offset = NULL;
if (semantic_name == TGSI_SEMANTIC_COLOR && key.light_twoside) {
bcolorAttrib = locate_linkage(
TGSI_SEMANTIC_BCOLOR, semantic_idx, pPrevShader) - 1;
TGSI_SEMANTIC_BCOLOR, semantic_idx, pPrevShader);
/* Neither front nor back colors were available. Nothing to load. */
if (bcolorAttrib == 0xFFFFFFFF && linkedAttrib == 0xFFFFFFFF)
continue;
/* If there is no front color, just always use the back color. */
if (linkedAttrib == 0xFFFFFFFF)
if (linkedAttrib + 1 == 0xFFFFFFFF)
linkedAttrib = bcolorAttrib;
if (bcolorAttrib != 0xFFFFFFFF) {
bcolorAttrib -= 1;
if (interpMode == TGSI_INTERPOLATE_CONSTANT) {
swr_fs->constantMask |= 1 << bcolorAttrib;
} else if (interpMode == TGSI_INTERPOLATE_COLOR) {
@@ -2797,6 +2807,7 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key)
}
sampler = swr_sampler_soa_create(key.sampler, PIPE_SHADER_FRAGMENT);
assert(sampler != nullptr);
struct lp_bld_tgsi_system_values system_values;
memset(&system_values, 0, sizeof(system_values));
+1
View File
@@ -71,6 +71,7 @@ swr_create_blend_state(struct pipe_context *pipe,
const struct pipe_blend_state *blend)
{
struct swr_blend_state *state = CALLOC_STRUCT(swr_blend_state);
assert(state != nullptr);
memcpy(&state->pipe, blend, sizeof(*blend));