@Test
	public void testBadAddressOffsetTracking() throws Exception {

		builder = new ProgramBuilder("thunk", ProgramBuilder._MIPS);

		builder.setBytes("0x1000",
			"3c 1c 00 14 27 9c b3 34 03 99 e0 21 27 bd ff e0" +
				"af bc 00 10 3c 07 12 34 24 e7 45 67 ac a7 00 10" +
				"3c 06 0a 0b 24 c6 0c 0d ae 06 00 10 8e 11 00 10" +
				"8c b1 00 10 8f b1 00 10 8e 51 00 10 ae 53 00 10" +
				"8e 51 00 10 36 92 00 00 8e 51 00 10 8e 92 00 10" +
				"3c 11 00 53 8e 51 00 10 03 e0 00 08 27 bd 00 20");

		//00001000        lui      gp,0x14
		//00001004        addiu    gp,gp,-0x4ccc
		//00001008        addu     gp,gp,t9
		//0000100c        addiu    sp,sp,-0x20
		//00001010        sw       gp,0x10(sp)
		//00001014        lui      a3,0x1234
		//00001018        addiu    a3,a3,0x4567
		//0000101c        sw       a3,0x10(a1)
		//00001020        lui      a2,0xa0b
		//00001024        addiu    a2,a2,0xc0d
		//00001028        sw       a2=>DAT_0a0b0c0d,0x10(s0)
		//0000102c        lw       s1,0x10(s0)
		//00001030        lw       s1,0x10(a1)
		//00001034        lw       s1,0x10(sp)
		//00001038        lw       s1,0x10(s2)
		//0000103c        sw       s3,0x10(s2)
		//00001040        lw       s1,0x10(s2)
		//00001044         ori      s2,s4,0x0
		//00001048         lw       s1,0x10(s2)
		//0000104c         lw       s2,0x10(s4)
		//00001050         lui      s1=>DAT_00530000,0x53
		//00001054         lw       s1,0x10(s2)
		//00001058         jr       ra
		//0000105c         _addiu   sp,sp,0x20

		builder.disassemble("0x1000", 88, false);

		builder.createFunction("0x1000");

		analyzer = new ConstantPropagationAnalyzer();

		program = builder.getProgram();
		program.startTransaction("Test");

		Address codeStart = addr("0x1000");
		Listing listing = program.getListing();
		assertNotNull("Bad instruction disassembly", listing.getInstructionAt(codeStart));

		setRegister(addr("0x1000"), "gp", 0x11200000);

		// follow all flows building up context
		// use context to fill out addresses on certain instructions 
		ContextEvaluator eval = new ConstantPropagationContextEvaluator(TaskMonitor.DUMMY, true) {
			@Override
			public boolean evaluateContextBefore(VarnodeContext context, Instruction instr) {

				// TODO Auto-generated method stub
				return super.evaluateContextBefore(context, instr);
			}

			@Override
			public boolean evaluateContext(VarnodeContext context, Instruction instr) {
				String loc = instr.getMinAddress().toString();
				Varnode registerVarnode;
				Long constVal;
				boolean isBad = false;

				switch(loc) {
				case "00001010":
					// gp should be 0x14 + t9 offset space
					registerVarnode = regValue(context,"gp");
					assertTrue("symbolic value", context.isSymbol(registerVarnode));
					assertEquals("(t9, 0x13b334, 4)", registerVarnode.toString());
					// S3 should be S3 at entry
					registerVarnode = regValue(context,"s3");
					assertTrue("register s3", context.isRegister(registerVarnode));
					assertEquals("s3", context.getRegister(registerVarnode).getName());
					break;
				case "0000102c":
					// s1 restored from space 0x10(s0) space
					registerVarnode = regValue(context,"s1");
					assertTrue("constant value", registerVarnode.isConstant());
					assertEquals("(const, 0xa0b0c0d, 4)", registerVarnode.toString());
					break;
				case "00001030":
					// s1 restored from space 0x10(a1) space
					registerVarnode = regValue(context,"s1");
					assertTrue("symbolic value", registerVarnode.isConstant());
					assertEquals("(const, 0x12344567, 4)", registerVarnode.toString());
					break;
				case "00001034":
					// s1 restored from space 0x10(sp) space
					registerVarnode = regValue(context,"s1");
					assertTrue("symbolic value", context.isSymbol(registerVarnode));
					assertEquals("(t9, 0x13b334, 4)", registerVarnode.toString());
					break;
				case "00001038":
					// s1 restored from space 0x10(s2) space
					registerVarnode = regValue(context,"s1");
					//assertTrue("Still s1", registerVarnode.isRegister());
					constVal = context.getConstant(registerVarnode, null);
					isBad = constVal == null;
					assertTrue("Can get constant value", isBad);
					break;
				case "00001040":
					// s1 restored from space 0x10(s2) space - stored a3
					registerVarnode = regValue(context,"s1");
					assertTrue("register s3", registerVarnode.isRegister());
					assertEquals("s3", context.getRegister(registerVarnode).getName());
					
					Address lastSetLocation = context.getLastSetLocation(context.getRegisterVarnode(context.getRegister("s2")), null);
					assertEquals("s2 last set", null, lastSetLocation);
					break;
				case "00001048":
					// s1 restored from space 0x10(s2) after s2 has been set again
					// it should no longer be s3 that was stored in another s2 relative space
					registerVarnode = regValue(context,"s1");
					//assertTrue("Still s1", registerVarnode.isRegister());
					constVal = context.getConstant(registerVarnode, null);
					isBad = constVal == null;
					assertTrue("Can get constant value", isBad);
					break;
				case "0000104c":
					// s1 restored from space 0x10(s2) after s2 has been set again
					// it should no longer be s3 that was stored in another s2 relative space
					registerVarnode = regValue(context,"s2");
					//assertTrue("Still s2", registerVarnode.isRegister());
					constVal = context.getConstant(registerVarnode, null);
					isBad = constVal == null;					
					assertTrue("Can get constant value", isBad);
					lastSetLocation = context.getLastSetLocation(context.getRegisterVarnode(context.getRegister("s2")), null);
					assertEquals("s2 last set", 0x104cL, lastSetLocation.getOffset());
					break;
				case "00001054":
					// s1 restored from space 0x10(s2) after s2 has been set again
					// it should no longer be s3 that was stored in another s2 relative space
					registerVarnode = regValue(context,"s1");
					//assertTrue("Still s1", registerVarnode.isRegister());
					//assertEquals(context.getRegister(registerVarnode).getName(),"s1");
					constVal = context.getConstant(registerVarnode, null);
					isBad = constVal == null;
					assertTrue("Can get constant value", isBad);
					break;
				}
				return super.evaluateContext(context, instr);
			}
		};

		setRegister(addr("0x1000"), "s1", 0);
		SymbolicPropogator symEval = new SymbolicPropogator(program,true);

		Function func = program.getFunctionManager().getFunctionAt(builder.addr(0x1000));

		symEval.flowConstants(codeStart, func.getBody(), eval, true, TaskMonitor.DUMMY);
		
		Value registerValue;
		
		// get gp at start of instruction
		registerValue = regValue(symEval, addr("0x1010"), "gp");
		assertNotNull(registerValue);
		assertTrue(registerValue.isRegisterRelativeValue());
		assertEquals(registerValue.getRelativeRegister().getName(), "t9");
		assertEquals(registerValue.getValue(), 0x13b334L);
		
		// get s1 at start of instruction
		registerValue = regValue(symEval, addr("0x1034"), "s1");
		assertNotNull(registerValue);
		assertFalse(registerValue.isRegisterRelativeValue());
		assertEquals(registerValue.getValue(), 0x12344567L);
		
		// get s1 at end of instruction
		registerValue = regEndValue(symEval, addr("0x1034"), "s1");
		assertNotNull(registerValue);
		assertTrue(registerValue.isRegisterRelativeValue());
		assertEquals(registerValue.getRelativeRegister().getName(), "t9");
		assertEquals(registerValue.getValue(), 0x13b334L);
		
		// get sp at end of instruction
		registerValue = regValue(symEval, addr("0x1058"), "sp");
		assertNotNull(registerValue);
		assertTrue(registerValue.isRegisterRelativeValue());
		assertEquals(registerValue.getRelativeRegister().getName(), "sp");
		assertEquals(-32, registerValue.getValue());
		
		// TODO: should be 0 at end
		// registerValue = regEndValue(symEval, addr("0x1058"), "sp");
		// assertEquals(0, registerValue.getValue());
	}
quick and dirty test of the ProgramContextImpl just to see
if the values are being set for specified address range.
The ProgramContextPlugin will be a more complete test
program, with a gui interface to specify the values and
select/highlight an address range.
Ghidra/Features/Base/src/test/java/ghidra/program/util/ConstantPropogationReferenceTest.java