private void addParamReferences(Function func, Address callTarget, Instruction instruction,
			VarnodeContext varnodeContext, TaskMonitor monitor) {

		if (!checkForParamRefs) {
			return;
		}

		// find the calling conventions
		// look up any register parameters
		//     get the value of each, as soon as find no value, stop
		//     look back to see when register value was set
		//     add a reference on to the register at that point
		PrototypeModel conv;
		conv = program.getCompilerSpec().getDefaultCallingConvention();

		int extraParamIndex = -1;
		
		Parameter[] params = new Parameter[0];
		SourceType signatureSource = SourceType.DEFAULT;
		if (func != null) {
			PrototypeModel funcConv = func.getCallingConvention();
			if (funcConv != null) {
				conv = funcConv;
			}
			params = func.getParameters();
			// if function is in a namespace, add an extra param index to check, params could be off by thisCall
			//  not being set
			Namespace parentNamespace = func.getParentNamespace();
			if (parentNamespace != null && parentNamespace instanceof GhidraClass) {
				PrototypeModel thisConv = program.getCompilerSpec().getCallingConvention(CompilerSpec.CALLING_CONVENTION_thiscall);
				if (conv != thisConv) {
					extraParamIndex = params.length;
				}
			}
			signatureSource = func.getSignatureSource();
		}
		else if (checkForParamPointerRefs) {
			// no function chan't check for pointer types
			return;
		}

		long callOffset = (callTarget == null ? -1 : callTarget.getOffset());

		// If there are params defined or the params were specified (meaning it could be VOID params)
		boolean signatureAssigned = signatureSource != SourceType.DEFAULT;
		boolean trustSignature = signatureAssigned || params.length > 0;
		if (trustSignature && !func.hasVarArgs()) {
			// Loop through defined parameters for a valid address value
			for (Parameter param : params) {
				Parameter p = param;

				// check if known pointer DT.
				//  construct pointer of the right type, given the constant
				// if not a pointer && flag must be pointer, don't add pointer
				DataType dataType = p.getDataType();

				if (!(dataType instanceof Pointer ||
				      (dataType instanceof TypeDef && ((TypeDef) dataType).isPointer()))) {
					// wasn't a pointer immediately
					if (checkForParamPointerRefs) {
						continue;
					}
					if (dataType instanceof TypeDef tdef) {
						dataType = tdef.getBaseDataType();
					}
					// if undefined, or int/long could still be pointer
					if (!(Undefined.isUndefined(dataType) || dataType instanceof IntegerDataType)) {
						continue;
					}
				}
				// use the varnode to pull out the bytes from the varnode
				//   only use constants, not symbolic?
				//   put the bytes in a membuffer
				//   Hand bytes to data type to decode as if in memory
				//   get pointer out
				createVariableStorageReference(instruction, varnodeContext, monitor, conv,
					p.getVariableStorage(), dataType, callOffset);
			}
			if (extraParamIndex != -1) {
				// TODO Should cache the arg locations for each convention
				VariableStorage var = conv.getArgLocation(extraParamIndex, null, pointerSizedDT, program);
				// can't trust stack storage if params aren't known
				if (!var.isStackStorage()) {
					createVariableStorageReference(instruction, varnodeContext, monitor, conv, var,
							null, callOffset);
				}
			}
		}
		else if (!checkForParamPointerRefs) {
			// loop through potential params, since none defined, to find a potential pointer
			// only check the first seven param locations, if don't have a signature
			for (int pi=0; pi < 8; pi++) {
				// TODO Should cache the arg locations for each convention
				VariableStorage var = conv.getArgLocation(pi, null, pointerSizedDT, program);
				// can't trust stack storage if params aren't known
				if (var.isStackStorage()) {
					continue;
				}
				createVariableStorageReference(instruction, varnodeContext, monitor, conv, var,
						null, callOffset);
			}
		}
	}
Modify the function purge by any stack depth override

@param prog program
@param addr addr of instruction that could have an override of the stack depth
@param purge current purge depth.
@return new purge, which includes the extrapop value
Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java