private void analyzeFunction(HashMap<Address, Long> constUse, DecompInterface decompInterface,
			Program prog, Function f, Address refAddr, FunctionParamUse funcVarUse, int paramIndex,
			ArrayList<PcodeOp> defUseList, ArrayList<FunctionParamUse> funcList) {
		if (f == null) {
			return;
		}

		decompileFunction(f, decompInterface);

		Instruction instr = prog.getListing().getInstructionAt(refAddr);
		if (hfunction == null) {
			return;
		}
		Iterator<PcodeOpAST> ops = hfunction.getPcodeOps(refAddr.getPhysicalAddress());
		while (ops.hasNext() && !monitor.isCancelled()) {
			PcodeOpAST pcodeOpAST = ops.next();
			if (pcodeOpAST.getOpcode() == PcodeOp.CALL) {
				// get the second parameter
				Varnode parm = pcodeOpAST.getInput(paramIndex + 1); // 1st param is the call dest
				if (parm == null) {
					constUse.put(instr.getAddress(), null);
					String problem = "  *** Warning, it appears that function '" +
						funcVarUse.getName() + "' at " + funcVarUse.getAddress() +
						" does not have it's parameters recovered!\n" +
						"        Use Commit Params/Return in the decompiler on this function.";
					addErrorNote(instr.getAddress(), problem);
					break;
				}
				// see if it is a constant
				if (parm.isConstant() || parm.isAddress()) {
					// then this is a resource id
					// lookup the resource and create a reference
					long value = parm.getOffset();
					// TODO: not so fast, if there is a defUseList, must apply
					// it to get the real constant USED!
					try {
						value = applyDefUseList(value, defUseList);
						constUse.put(instr.getAddress(), value);
						println("   " + f.getName() + "    " + instr.getAddress() + " : 0x" +
							Long.toHexString(value));
					}
					catch (InvalidInputException exc) {
						// do nothing
					}
				}
				else {
					followToParam(constUse, defUseList, hfunction, parm, funcList, null);
				}
				break;
				// if this is anything else, get the high variable to see if it
				// can be traced back to a param
				// then repeat with any calls to this function at whatever the
				// param is
			}
			else if (pcodeOpAST.getOpcode() == PcodeOp.BRANCH) {
				Address faddr = pcodeOpAST.getInput(0).getAddress();
				if (funcVarUse == null || faddr == null) {
					continue;
				}
				if (!faddr.equals(funcVarUse.getAddress())) {
					continue;
				}
				Varnode rep = funcVarUse.getRepresentative();
				if (rep == null) {
					continue;
				}
				followToParam(constUse, defUseList, hfunction, rep, funcList, null);
			}
		}
	}
Backtrack to a constant given a start position of a parameter of a given
function Useful if you want to start from a function paramter.

@param f function to start in
@param paramIndex parameter index to backtrack from
@param tableChooserDialog accumulate entries. Don't like passing it, but this way the
        user gets immediate feedback as locations are found
@return a map of Addresses to constants (constants could be NULL)
@throws CancelledException if cancelled
Ghidra/Features/Decompiler/ghidra_scripts/ShowConstantUse.java