ghidra.program.model.listing.Instruction Java Examples

The following examples show how to use ghidra.program.model.listing.Instruction. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: HCS12ConventionAnalyzer.java    From ghidra with Apache License 2.0 6 votes vote down vote up
private void setPrototypeModel(Program program, Instruction instr, String convention) {
	if (convention == null) {
		return;
	}

	Function func = program.getFunctionManager().getFunctionContaining(instr.getMinAddress());
	if (func == null) {
		return;
	}

	if (func.getSignatureSource() != SourceType.DEFAULT) {
		return;
	}

	try {
		func.setCallingConvention(convention);
	} catch (InvalidInputException e) {
		Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
	}
}
 
Example #2
Source File: CodeUnitMergeManagerOverrideTest.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * Fallthrough override from 0100354f to 01003559.
 * @param program override the flow in this program.
 * @param description description for the transaction that overrides the flow.
 */
private void fallthroughOverride(ProgramDB program, String description) {
	int txId = program.startTransaction(description);
	boolean commit = false;
	try {
		// Fallthrough override from 0100354f to 01003559.
		Instruction instruction =
			program.getListing().getInstructionAt(addr(program, "0100354f"));
		instruction.setFallThrough(addr(program, "01003559"));
		commit = true;
		assertEquals(addr(program, "01003559"), instruction.getFallThrough());
		assertEquals(FlowOverride.NONE, instruction.getFlowOverride());
	}
	finally {
		program.endTransaction(txId, commit);
	}
	ReferenceManager refMgr = program.getReferenceManager();
	Reference[] referencesFrom = refMgr.getReferencesFrom(addr(program, "0100354f"), 1);
	assertEquals(0, referencesFrom.length);
}
 
Example #3
Source File: EquatePlugin1Test.java    From ghidra with Apache License 2.0 6 votes vote down vote up
@Test
public void testConvertChar() {
	putCursorOnOperand(0x01004e4a, 0);

	Instruction inst = listing.getInstructionAt(addr(0x01004e4a));
	Scalar scalar = inst.getScalar(0);

	performAction("Convert To Char");

	ListingTextField tf = (ListingTextField) cb.getCurrentField();
	assertEquals("'" + new String(new byte[] { (byte) scalar.getUnsignedValue() }) + "'",
		tf.getFieldElement(0, 11).getText());

	undo(program);
	tf = (ListingTextField) cb.getCurrentField();
	assertEquals("0x" + Long.toString(scalar.getUnsignedValue(), 16),
		tf.getFieldElement(0, 11).getText());

	redo(program);
	tf = (ListingTextField) cb.getCurrentField();
	assertEquals("'" + new String(new byte[] { (byte) scalar.getUnsignedValue() }) + "'",
		tf.getFieldElement(0, 11).getText());
}
 
Example #4
Source File: AssembleScript.java    From ghidra with Apache License 2.0 6 votes vote down vote up
@Override
public void run() throws Exception {
	monitor.setMessage("Constructing Assember");
	// First, obtain an assembler bound to the current program.
	// If a suitable assembler has not yet been build, this will take some time to build it.
	Assembler asm = Assemblers.getAssembler(currentProgram);

	monitor.setMessage("Awaiting Input");
	// Put the current instruction text in by default.
	Instruction ins = getInstructionAt(currentAddress);
	String cur = "";
	if (ins != null) {
		cur = ins.toString();
	}

	// Now present the prompt and assemble the given text.
	// The assembler will patch the result into the bound program.
	asm.assemble(currentAddress, askString("Assemble", "Type an instruction", cur));
}
 
Example #5
Source File: Emulate.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * Get length of instruction including any delay-slotted instructions.
 * Must be called by emitPcode with lastPseudoInstructionBlock properly set.
 * @param instr
 * @return length of instruction in bytes for use in computing fall-through location
 */
private int getInstructionLength(Instruction instr) throws InstructionDecodeException {
	int length = instr.getLength();
	int delaySlots = instr.getDelaySlotDepth();
	while (delaySlots != 0) {
		try {
			Address nextAddr = instr.getAddress().addNoWrap(instr.getLength());
			Instruction nextInstr = lastPseudoInstructionBlock.getInstructionAt(nextAddr);
			if (nextInstr == null) {
				throw new InstructionDecodeException("Failed to parse delay slot instruction",
					nextAddr);
			}
			instr = nextInstr;
			length += instr.getLength();
			--delaySlots;
		}
		catch (AddressOverflowException e) {
			throw new InstructionDecodeException(
				"Failed to parse delay slot instruction at end of address space",
				instr.getAddress());
		}
	}
	return length;
}
 
Example #6
Source File: ConstantPropagationContextEvaluator.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
    * If you override this method, and the default behavior of checking 0-256 and mask values is desired,
    * call super.evaluateConstant() in your overriden method.
    */
   @Override
public Address evaluateConstant(VarnodeContext context, Instruction instr, int pcodeop,
		Address constant, int size, RefType refType) {
	
	// Constant references below minSpeculative or near the end of the address space are suspect,
   	// even if memory exists for those locations.
	AddressSpace space = constant.getAddressSpace();
	long maxAddrOffset = space.getMaxAddress().getOffset();
	long wordOffset = constant.getOffset();

	if (((wordOffset >= 0 && wordOffset < minSpeculativeOffset) ||
		(Math.abs(maxAddrOffset - wordOffset) < maxSpeculativeOffset)) &&
		!space.isExternalSpace()) {
		return null;
	}
	
	// could just be integer -1 extended into address
	if (wordOffset == 0xffffffffL || wordOffset == 0xffffL || wordOffset == -1L) {
		return null;
	}

	return constant;
}
 
Example #7
Source File: EquatePlugin1Test.java    From ghidra with Apache License 2.0 6 votes vote down vote up
@Test
public void testConvertToUnsignedHex() {

	putCursorOnOperand(0x010065a7, 1);

	Instruction inst = listing.getInstructionAt(addr(0x010065a7));
	Scalar scalar = inst.getScalar(1);

	performAction("Convert To Unsigned Hex");

	ListingTextField tf = (ListingTextField) cb.getCurrentField();
	assertEquals("0x" + Long.toString(scalar.getUnsignedValue(), 16),
		tf.getFieldElement(0, 23).getText());

	undo(program);
	tf = (ListingTextField) cb.getCurrentField();
	assertEquals("0x" + Long.toString(scalar.getUnsignedValue(), 16),
		tf.getFieldElement(0, 23).getText());

	redo(program);
	tf = (ListingTextField) cb.getCurrentField();
	assertEquals("0x" + Long.toString(scalar.getUnsignedValue(), 16),
		tf.getFieldElement(0, 23).getText());
}
 
Example #8
Source File: ConstantPropagationContextEvaluator.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * Add instructions to destination set for unknown computed branches.
 */
@Override
public boolean evaluateDestination(VarnodeContext context, Instruction instruction) {
	FlowType flowType = instruction.getFlowType();
	if (!flowType.isJump()) {
		return false;
	}

	/**
	 * For jump targets, that have no computed reference, add the jump location to a set
	 * to evaluate as a potential switch statement.
	 */
	Reference[] refs = instruction.getReferencesFrom();
	if (refs.length <= 0 || (refs.length == 1 && refs[0].getReferenceType().isData())) {
		destSet.addRange(instruction.getMinAddress(), instruction.getMinAddress());
	}
	return false;
}
 
Example #9
Source File: EquateDB.java    From ghidra with Apache License 2.0 6 votes vote down vote up
private short findScalarOpIndex(Instruction instr) {
	short opIndex = -1;
	long value = record.getLongValue(EquateDBAdapter.VALUE_COL);
	int numOperands = instr.getNumOperands();
	for (short i = 0; i < numOperands; i++) {
		for (Object obj : instr.getOpObjects(i)) {
			if (obj instanceof Scalar) {
				if (((Scalar) obj).getValue() != value) {
					continue;
				}
				if (opIndex >= 0) {
					return -1; // non-unique scalar operand value - can't identify operand
				}
				opIndex = i;
			}
		}
	}
	return opIndex;
}
 
Example #10
Source File: HCS12ConventionAnalyzer.java    From ghidra with Apache License 2.0 6 votes vote down vote up
@Override
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
		throws CancelledException {

	// get all functions within the set
	FunctionIterator functions = program.getFunctionManager().getFunctions(set, true);
	for (Function function : functions) {

		// for each function body, search instructions
		AddressSetView body = function.getBody();
		InstructionIterator instructions = program.getListing().getInstructions(body, true);
		for (Instruction instr : instructions) {
			if (instr.getFlowType().isTerminal()) {
				checkReturn(program, instr);
			}
		}
	}
	return true;
}
 
Example #11
Source File: HCS12ConventionAnalyzer.java    From ghidra with Apache License 2.0 6 votes vote down vote up
void checkReturn(Program program, Instruction instr) {
	String mnemonic = instr.getMnemonicString().toLowerCase();

	if (instr == null || !instr.getFlowType().isTerminal()) {
		return;
	}

	// if XGATE set on instruction is XGATE
	RegisterValue xgateValue = program.getProgramContext().getRegisterValue(xgate, instr.getMinAddress());
	if (xgateValue != null && xgateValue.hasValue() && xgateValue.getUnsignedValue().equals(BigInteger.ONE)) {
		setPrototypeModel(program, instr, "__asm_xgate");
		return;
	}

	// set the correct convention
	if (mnemonic.equals("rtc")) {
		setPrototypeModel(program, instr, "__asmA_longcall");
		return;
	}

	if (mnemonic.equals("rts")) {
		setPrototypeModel(program, instr, "__asmA");
		return;
	}

}
 
Example #12
Source File: EquatePlugin1Test.java    From ghidra with Apache License 2.0 6 votes vote down vote up
@Test
public void testConvertOctal() {

	putCursorOnOperand(0x01005a01, 1);

	Instruction inst = listing.getInstructionAt(addr(0x01005a01));
	Scalar scalar = inst.getScalar(1);

	performAction("Convert To Unsigned Octal");

	ListingTextField tf = (ListingTextField) cb.getCurrentField();
	assertEquals(Long.toString(scalar.getUnsignedValue(), 8) + "o",
		tf.getFieldElement(0, 11).getText());

	undo(program);
	tf = (ListingTextField) cb.getCurrentField();
	assertEquals("0x" + Long.toString(scalar.getSignedValue(), 16),
		tf.getFieldElement(0, 11).getText());

	redo(program);
	tf = (ListingTextField) cb.getCurrentField();
	assertEquals(Long.toString(scalar.getUnsignedValue(), 8) + "o",
		tf.getFieldElement(0, 11).getText());

}
 
Example #13
Source File: InstructionBlock.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * Adds an instruction to this block.  If the block in not empty, the newly added instruction
 * must be directly after the current block maximum address.  In other words, all instructions
 * int the block must be consecutive.
 * @param instruction the instruction to add to this block.
 * @throws IllegalArgumentException if the new instruction does not immediately follow the
 * last instruction added.
 */
public void addInstruction(Instruction instruction) {
	Address instructionMinAddr = instruction.getMinAddress();
	if (maxAddress == null) {
		if (!instructionMinAddr.equals(startAddr)) {
			throw new IllegalArgumentException("First instruction to block had address " +
				instructionMinAddr + ", expected address " + startAddr);
		}
	}
	else if (!maxAddress.isSuccessor(instructionMinAddr)) {
		throw new IllegalArgumentException("Newly added instruction at address " +
			instructionMinAddr + " is not the immediate succesor to address " + maxAddress);
	}
	instructionMap.put(instructionMinAddr, instruction);
	if (!instruction.isInDelaySlot()) {
		lastInstructionAddress = instruction.getMinAddress();
	}
	maxAddress = instruction.getMaxAddress();
}
 
Example #14
Source File: EquatePlugin1Test.java    From ghidra with Apache License 2.0 6 votes vote down vote up
@Test
public void testConvertCharUnprintable() {
	putCursorOnOperand(0x0100519f, 0);

	Instruction inst = listing.getInstructionAt(addr(0x0100519f));
	Scalar scalar = inst.getScalar(0);
	assertEquals(2, scalar.getUnsignedValue());

	performAction("Convert To Char");

	ListingTextField tf = (ListingTextField) cb.getCurrentField();
	assertEquals("02h", tf.getFieldElement(0, 11).getText());

	undo(program);
	tf = (ListingTextField) cb.getCurrentField();
	assertEquals("0x" + Long.toString(scalar.getUnsignedValue(), 16),
		tf.getFieldElement(0, 11).getText());

	redo(program);
	tf = (ListingTextField) cb.getCurrentField();
	assertEquals("02h", tf.getFieldElement(0, 11).getText());
}
 
Example #15
Source File: EquatePlugin1Test.java    From ghidra with Apache License 2.0 6 votes vote down vote up
@Test
public void testConvertToUnsignedDecimal() {
	// create an unsigned decimal as the equate name
	putCursorOnOperand(0x010059ef, 1);
	ComponentProvider provider = tool.getComponentProvider(PluginConstants.CODE_BROWSER);

	Instruction inst = listing.getInstructionAt(addr(0x010059ef));
	Scalar scalar = inst.getScalar(1);

	DockingActionIf action = getAction(equatePlugin, "Convert To Unsigned Decimal");
	performAction(action, provider, true);
	waitForTasks();

	ListingTextField tf = (ListingTextField) cb.getCurrentField();
	assertEquals(Long.toString(scalar.getUnsignedValue(), 10),
		tf.getFieldElement(0, 11).getText());

	undo(program);
	tf = (ListingTextField) cb.getCurrentField();
	assertEquals("-0x1", tf.getFieldElement(0, 11).getText());

	redo(program);
	tf = (ListingTextField) cb.getCurrentField();
	assertEquals("4294967295", tf.getFieldElement(0, 11).getText());
}
 
Example #16
Source File: InstructionBlock.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * Find the first instruction within this block which intersects the specified range.
 * This method should be used sparingly since it uses a brute-force search.
 * @param min the minimum intersection address
 * @param max the maximum intersection address
 * @return instruction within this block which intersects the specified range or null
 * if not found 
 */
public Instruction findFirstIntersectingInstruction(Address min, Address max) {
	Instruction intersectInstr = null;
	for (Instruction instr : instructionMap.values()) {
		Address instrMin = instr.getMinAddress();
		if (instrMin.compareTo(max) > 0) {
			continue;
		}
		Address instrMax = instr.getMaxAddress();
		if (instrMax.compareTo(min) < 0) {
			continue;
		}
		if (intersectInstr != null && intersectInstr.getAddress().compareTo(instrMin) < 0) {
			continue;
		}
		intersectInstr = instr;
	}
	return intersectInstr;
}
 
Example #17
Source File: ExactMnemonicsFunctionHasher.java    From ghidra with Apache License 2.0 5 votes vote down vote up
@Override
protected long hash(TaskMonitor monitor, ArrayList<CodeUnit> units, int byteCount)
		throws MemoryAccessException, CancelledException {
	StringBuilder sb = new StringBuilder();
	for (CodeUnit codeUnit : units) {
		monitor.checkCanceled();

		if (codeUnit instanceof Instruction) {
			Instruction inst = (Instruction) codeUnit;
			String mnemonic = inst.getMnemonicString();
			sb.append(mnemonic);
			// this is not allowed to be part of a mnemonic name, so it works as a separator
			sb.append("\n");
			sb.append(inst.getNumOperands());
		}
		else {
			try {
				byte[] bytes = codeUnit.getBytes();
				char[] chars = new char[bytes.length];
				for (int ii = 0; ii < bytes.length; ++ii) {
					chars[ii] = (char) bytes[ii];
				}
				sb.append(chars);
			}
			catch (MemoryAccessException e) {
				Msg.warn(this, "Could not get code unit bytes at " + codeUnit.getAddress());
				sb.append(codeUnit.getAddressString(true, true));
			}
		}
		// this is not allowed to be part of a mnemonic name, so it works as a separator
		sb.append("\n");
	}
	synchronized (digest) {
		digest.reset();
		digest.update(sb.toString().getBytes(), monitor);
		return digest.digestLong();
	}
}
 
Example #18
Source File: ParallelInstructionFieldFactory.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the FactoryField for the given object at index index.
 * @param varWidth the amount of variable width spacing for any fields
 * before this one.
 * @param proxy the object whose properties should be displayed.
 */
@Override
public ListingField getField(ProxyObj proxy, int varWidth) {
	Object obj = proxy.getObject();

	if (!enabled || !(obj instanceof Instruction)) {
		return null;
	}

	Instruction instr = (Instruction) obj;
	ParallelInstructionLanguageHelper helper =
		instr.getProgram().getLanguage().getParallelInstructionHelper();
	if (helper == null) {
		return null;
	}

	String fieldText = helper.getMnemonicPrefix(instr);
	if (fieldText == null) {
		return null;
	}

	AttributedString as =
		new AttributedString(fieldText, color, getMetrics(), false, underlineColor);
	FieldElement text = new TextFieldElement(as, 0, 0);
	return ListingTextField.createSingleLineTextField(this, proxy, text, startX + varWidth,
		width, hlProvider);
}
 
Example #19
Source File: ParallelInstructionFieldFactory.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * @see ghidra.app.util.viewer.field.FieldFactory#getProgramLocation(int, int, ghidra.app.util.viewer.field.ListingField)
 */
@Override
public ProgramLocation getProgramLocation(int row, int col, ListingField bf) {
	Object obj = bf.getProxy().getObject();
	if (!(obj instanceof Instruction)) {
		return null;
	}
	Instruction instr = (Instruction) obj;

	return new ParallelInstructionLocation(instr.getProgram(), instr.getMinAddress(), col);
}
 
Example #20
Source File: FallThroughPlugin.java    From ghidra with Apache License 2.0 5 votes vote down vote up
Instruction getInstruction(ListingActionContext context) {
	Address address = context.getAddress();
	if (address != null) {
		return context.getProgram().getListing().getInstructionAt(address);
	}
	return null;
}
 
Example #21
Source File: VxWorksSymTab_Finder.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private void clearString(Address addr) throws Exception {
	Data data;
	Instruction inst;

	// Clear the string, breaking on the terminating null character
	while (getByte(addr) != 0) {
		data = getDataContaining(addr);
		if (data != null) {
			removeDataAt(data.getAddress());
		}
		inst = getInstructionContaining(addr);
		if (inst != null) {
			removeInstructionAt(inst.getAddress());
		}

		addr = addr.add(1);
	}

	// Now clear at string's terminating null character
	data = getDataContaining(addr);
	if (data != null) {
		removeDataAt(data.getAddress());
	}
	inst = getInstructionContaining(addr);
	if (inst != null) {
		removeInstructionAt(inst.getAddress());
	}
}
 
Example #22
Source File: InstructionStasher.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private void clearAndSave() {
	Instruction instruction = program.getListing().getInstructionContaining(address);
	if (instruction == null) {
		return;
	}
	minAddress = instruction.getMinAddress();
	prototype = instruction.getPrototype();
	referencesFrom = instruction.getReferencesFrom();
	program.getListing().clearCodeUnits(minAddress, instruction.getMaxAddress(), false);
}
 
Example #23
Source File: RefTypeFactory.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Determine default computed FlowType for a specified instruction.  It is assumed 
 * that all computed flows utilize a register in its destination specification/computation.
 * @param instr instruction
 * @return FlowType or null if unable to determine
 */
public static FlowType getDefaultComputedFlowType(Instruction instr) {

	if (instr.getFlowType() != RefType.INVALID && instr.getDefaultFlows().length <= 1) {
		// Don't bother looking if not complex flow
		return getDefaultJumpOrCallFlowType(instr);
	}

	// Assumption - it is assumed that any complex flow type is due to the presence of
	// multiple conditional flows.  

	// TODO: Verify that above assumption is valid !!

	FlowType flowType = null;
	PcodeOp[] pcodeOps = instr.getPcode();
	for (PcodeOp op : pcodeOps) {
		int opcode = op.getOpcode();
		if (opcode == PcodeOp.BRANCHIND) {
			if (flowType == RefType.CONDITIONAL_COMPUTED_CALL) {
				return null; // more than one flow type
			}
			flowType = RefType.CONDITIONAL_COMPUTED_JUMP;
		}
		else if (opcode == PcodeOp.CALLIND) {
			if (flowType == RefType.CONDITIONAL_COMPUTED_JUMP) {
				return null; // more than one flow type
			}
			flowType = RefType.CONDITIONAL_COMPUTED_CALL;
		}
	}

	return flowType;
}
 
Example #24
Source File: InstructionMaskValueFieldFactory.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * @see ghidra.app.util.viewer.field.FieldFactory#getProgramLocation(int, int, ghidra.app.util.viewer.field.ListingField)
 */
@Override
public ProgramLocation getProgramLocation(int row, int col, ListingField bf) {
	Object obj = bf.getProxy().getObject();
	if (!(obj instanceof Instruction)) {
		return null;
	}
	Instruction instr = (Instruction) obj;

	return new InstructionMaskValueFieldLocation(instr.getProgram(), instr.getMinAddress(), row,
		col);
}
 
Example #25
Source File: ClearFallThroughCmd.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
* 
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
  public boolean applyTo(DomainObject obj) {
  	Program program = (Program)obj;
  	Instruction inst = program.getListing().getInstructionAt(instAddr);
  	inst.clearFallThroughOverride();
  	return true;
  }
 
Example #26
Source File: ScalarOperandListingHover.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private Object getOperand(OperandFieldLocation loc, Instruction instruction) {
	int opIndex = loc.getOperandIndex();
	Object[] operands = instruction.getOpObjects(opIndex);
	if (operands.length == 1) {
		return operands[0];
	}

	InstructionPrototype prototype = instruction.getPrototype();
	List<Object> list =
		prototype.getOpRepresentationList(opIndex, instruction.getInstructionContext());
	if (list == null) {
		return null;
	}
	return list.get(loc.getSubOperandIndex());
}
 
Example #27
Source File: InstructionError.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private static String getInstructionDetails(Instruction instr) {
	StringBuilder buf = new StringBuilder();
	buf.append(instr.toString());
	buf.append("\n");
	buf.append(InstructionUtils.getFormattedContextRegisterValueBreakout(instr, "     "));
	return buf.toString();
}
 
Example #28
Source File: InstructionError.java    From ghidra with Apache License 2.0 5 votes vote down vote up
public static void dumpInstructionDifference(Instruction newInst, Instruction existingInstr) {
	StringBuilder buf =
		new StringBuilder("Instruction conflict details at " + newInst.getAddress());
	buf.append("\n  New Instruction: ");
	buf.append(getInstructionDetails(newInst));
	buf.append("\n  Existing Instruction: ");
	buf.append(getInstructionDetails(existingInstr));
	Msg.debug(InstructionError.class, buf.toString());
}
 
Example #29
Source File: ShowInstructionInfoPluginTest.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private void clearAt100000() {
	int transactionID = program.startTransaction("Test");
	Address start = addr(0x01000000);
	Instruction inst = program.getListing().getInstructionAt(start);
	try {
		program.getListing().clearCodeUnits(start, inst.getMaxAddress(), false);
	}
	finally {
		program.endTransaction(transactionID, true);
	}

	waitForProgram(program);
}
 
Example #30
Source File: ShowInstructionInfoPluginTest.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Tests the addresses of the table models of the "Instruction Info" dialog.
 * The method will fail the current test if the result is not as 
 * expected by the caller of this method.  For example, if 
 * <tt>expectedSame</tt> is true, then the method expects the values to
 * be the same when compared with the given address and will fail if 
 * they are not.  If <tt>expectedSame</tt> is false, then the method will
 * fail if the test values are the same.
 * 
 * @param instructionAddress The address to compare against the address
 *        stored in the table model of the dialog.
 * @param expectedSame True means a match is expected; false means a 
 *        match is not expected.
 */
private void verifyAddressWithTableModels(Address instructionAddress, boolean fromConnected,
		boolean expectedSame) {
	ComponentProvider provider = fromConnected ? getCurrentComponentProviderFromPlugin()
			: getFirstDisconnectedProviderFromPlugin();

	JTextArea instructionText = (JTextArea) getInstanceField("instructionText", provider);
	JTable opTable = (JTable) getInstanceField("opTable", provider);

	// get the instruction address from each table model and make sure that
	// it is the same as the current instruction
	String stateString = expectedSame ? "is not" : "is";
	String text = instructionText.getText();

	String address = instructionAddress.toString(true);
	Pattern pattern = Pattern.compile("Address\\s*:\\s*" + address);
	Matcher matcher = pattern.matcher(text);
	boolean comparisonResult = matcher.find();

	// if the caller of this method expects the results to be NOT equal, 
	// then toggle the comparison result
	if (!expectedSame) {
		comparisonResult = !comparisonResult;
	}

	assertTrue("The address of the mnemonic table " + stateString +
		" the same as that of the current program instruction.", comparisonResult);

	Instruction opInstr = (Instruction) getInstanceField("instruction", opTable.getModel());
	comparisonResult = instructionAddress.equals(opInstr.getMinAddress());

	if (!expectedSame) {
		comparisonResult = !comparisonResult;
	}

	assertTrue("The address of the op table " + stateString +
		" the same as that of the current program instruction.", comparisonResult);
}