Java Code Examples for ghidra.program.model.lang.Register#getName()

The following examples show how to use ghidra.program.model.lang.Register#getName() . 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: DiffUtility.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
	 * Returns a string representation of the specified address.
	 * @param program the program containing the address
	 * @param address the address
	 * @return the address as a meaningful string for the user.
	 */
	public static String getUserToAddressString(Program program, Address address) {
		if (address == null) {
			return ""; // Show nothing if no To Address.
		}
		if (address.isVariableAddress()) {
			// This should not occur with references
//			address = program.getVariableStorageManager().getStorageAddress(address);
//			if (address == null) {
//				return "Unknown";
//			}
		}
		if (address.isRegisterAddress()) {
			Register reg = program.getRegister(address);
			if (reg != null) {
				return "register:" + reg.getName();
			}
		}
		else if (address.isStackAddress()) {
			return "stack:" + toSignedHexString(address.getOffset());
		}
		return address.toString();
	}
 
Example 2
Source File: Varnode.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * Convert this varnode to an alternate String representation based on a specified language.
 * @param language
 * @return string representation
 */
public String toString(Language language) {
	if (isAddress() || isRegister()) {
		Register reg = language.getRegister(address, size);
		if (reg != null) {
			return reg.getName();
		}
	}
	if (isUnique()) {
		return "u_" + Long.toHexString(offset) + ":" + size;
	}
	if (isConstant()) {
		return "0x" + Long.toHexString(offset);
	}
	return "A_" + address + ":" + size;
}
 
Example 3
Source File: GraphAST.java    From ghidra with Apache License 2.0 5 votes vote down vote up
protected AttributedVertex createVarnodeVertex(VarnodeAST vn) {
	String name = vn.getAddress().toString(true);
	String id = getVarnodeKey(vn);
	String colorattrib = "Red";
	if (vn.isConstant()) {
		colorattrib = "DarkGreen";
	}
	else if (vn.isRegister()) {
		colorattrib = "Blue";
		Register reg = func.getProgram().getRegister(vn.getAddress(), vn.getSize());
		if (reg != null) {
			name = reg.getName();
		}
	}
	else if (vn.isUnique()) {
		colorattrib = "Black";
	}
	else if (vn.isPersistant()) {
		colorattrib = "DarkOrange";
	}
	else if (vn.isAddrTied()) {
		colorattrib = "Orange";
	}
	AttributedVertex vert = graph.addVertex(id, name);
	if (vn.isInput()) {
		vert.setAttribute(ICON_ATTRIBUTE, "TriangleDown");
	}
	else {
		vert.setAttribute(ICON_ATTRIBUTE, "Circle");
	}
	vert.setAttribute(COLOR_ATTRIBUTE, colorattrib);
	return vert;
}
 
Example 4
Source File: Lab5Script.java    From ghidra with Apache License 2.0 5 votes vote down vote up
@Override
public void run() throws Exception {
	Instruction instruction = getFirstInstruction();
	while (instruction != null) {
		if (monitor.isCancelled()) {
			break;
		}
		if (instruction.getNumOperands() != 2) {
			continue;
		}

		Object[] opObjects0 = instruction.getOpObjects(0);
		if (opObjects0.length != 1 || !(opObjects0[0] instanceof Register)) {
			continue;
		}

		Object[] opObjects1 = instruction.getOpObjects(1);
		if (opObjects1.length != 1 || !(opObjects1[0] instanceof Scalar)) {
			continue;
		}

		Register register = (Register) opObjects0[0];
		Scalar scalar = (Scalar) opObjects1[0];
		String comment =
			"[" + register.getName() + "]=[" + scalar.toString(16, false, false, "", "") + "]";
		setEOLComment(instruction.getMinAddress(), comment);
		instruction = getInstructionAfter(instruction);
	}
}
 
Example 5
Source File: DiffUtility.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the string representation of the specified reference's "to" address.
 * @param program the program containing the reference
 * @param ref the reference
 * @return the "to" address for the reference as a meaningful address for the user.
 */
public static String getUserToAddressString(Program program, Reference ref) {

	Address toAddr = ref.getToAddress();
	if (ref.isExternalReference()) {
		ExternalLocation extLoc = ((ExternalReference) ref).getExternalLocation();
		Address extAddr = extLoc.getAddress();
		String extLabel = extLoc.getLabel();
		return extLoc.getLibraryName() + "::" + (extLabel != null ? extLabel : "") +
			(extAddr != null ? (" (" + extAddr + ")") : "");
	}

	if (ref.isStackReference()) {
		int offset = ((StackReference) ref).getStackOffset();
		return "Stack[" + toSignedHexString(offset) + "]";
	}
	else if (ref.isOffsetReference()) {
		OffsetReference oref = (OffsetReference) ref;
		return toAddr.toString() + " " + "base:" +
			DiffUtility.getUserToAddressString(program, oref.getBaseAddress()) + " " +
			"offset:" + DiffUtility.toSignedHexString(oref.getOffset());

	}
	else if (ref.isShiftedReference()) {
		ShiftedReference sref = (ShiftedReference) ref;
		return toAddr.toString() + " " + "value:" + sref.getValue() + " " + "<<" +
			sref.getShift();
	}

	Register reg = program.getRegister(toAddr);
	if (reg != null) {
		return "register: " + reg.getName();
	}

	return toAddr.toString();

}
 
Example 6
Source File: RegisterFieldFactory.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private String[] getRegisterStrings(Function function, List<Register> setRegisters) {
	Program program = function.getProgram();
	ProgramContext programContext = program.getProgramContext();
	Address address = function.getEntryPoint();
	String[] strings = new String[setRegisters.size()];
	for (int i = 0; i < strings.length; i++) {
		Register register = setRegisters.get(i);
		BigInteger value = programContext.getValue(register, address, false);
		strings[i] = "assume " + register.getName() + " = 0x" + value.toString(16);
	}
	return strings;
}
 
Example 7
Source File: EditRegisterValueDialog.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private JComponent buildWorkPanel(Register register, Address start, Address end,
		BigInteger value, AddressFactory factory) {

	JTextField registerField =
		new JTextField(register.getName() + " (" + register.getBitLength() + ")");
	registerField.setEditable(false);

	startAddrField = new AddressInput();
	endAddrField = new AddressInput();
	ChangeListener changeListener = new ChangeListener() {
		@Override
		public void stateChanged(ChangeEvent e) {
			updateOk();
		}
	};
	startAddrField.setAddressFactory(factory);
	endAddrField.setAddressFactory(factory);
	startAddrField.addChangeListener(changeListener);
	endAddrField.addChangeListener(changeListener);

	registerValueField = new FixedBitSizeValueField(register.getBitLength(), true, false);
	startAddrField.setAddress(start);
	endAddrField.setAddress(end);
	registerValueField.setValue(value);

	JPanel panel = new JPanel(new PairLayout(5, 1));

	panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
	panel.add(new GLabel("Register:"));
	panel.add(registerField);
	panel.add(new GLabel("Start Address:"));
	panel.add(startAddrField);
	panel.add(new GLabel("End Address:"));
	panel.add(endAddrField);
	panel.add(new GLabel("Value:"));
	panel.add(registerValueField);

	return panel;
}
 
Example 8
Source File: ASTGraphTask.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private String translateVarnode(Varnode node, boolean useVarName) {
	if (node == null) {
		return "null";
	}
	Program p = hfunction.getFunction().getProgram();
	Address addr = node.getAddress();
	if (node.isConstant()) {
		return "#" + NumericUtilities.toHexString(addr.getOffset(), node.getSize());
	}
	else if (node.isUnique()) {
		return "u_" + Long.toHexString(addr.getOffset());
	}
	else if (addr.isRegisterAddress()) {
		Register r = p.getRegister(addr, node.getSize());
		if (r == null) {
			r = p.getRegister(addr);
		}
		if (r != null) {
			return r.getName();
		}
	}
	else if (addr.isStackAddress()) {
		if (useVarName) {
			HighVariable var = node.getHigh();
			if (var != null) {
				return var.getName();
			}
		}
		return "Stack[" + NumericUtilities.toSignedHexString(addr.getOffset()) + "]";
	}
	else if (addr.isMemoryAddress()) {
		return addr.toString(true);
	}
	return node.toString();
}
 
Example 9
Source File: DatabaseRangeMapAdapter.java    From ghidra with Apache License 2.0 5 votes vote down vote up
public DatabaseRangeMapAdapter(Register register, DBHandle dbHandle, AddressMap addrMap,
		Lock lock, ErrorHandler errorHandler) {
	this.dbh = dbHandle;
	this.errorHandler = errorHandler;
	mapName = NAME_PREFIX + register.getName();
	rangeMap =
		new AddressRangeMapDB(dbHandle, addrMap, lock, mapName, errorHandler,
			BinaryField.class, false);
	addressMap = addrMap;
}
 
Example 10
Source File: EmulatorConfiguration.java    From ghidra with Apache License 2.0 5 votes vote down vote up
default String getProgramCounterName() {
	Language lang = getLanguage();
	Register pcReg = lang.getProgramCounter();
	if (pcReg == null) {
		throw new IllegalStateException(
			"Language has not defined Program Counter Register: " + lang.getLanguageID());
	}
	return pcReg.getName();
}
 
Example 11
Source File: VariableImpl.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
 * Construct a variable.  Only one storage/location may be specified (storage, storageAddr,
 * stackOffset, register) - all others should be null.  If no storage/location is specified
 * or is UNASSIGNED, a Void data type may be specified and will be assumed if this type returns
 * true for {@link #isVoidAllowed()}.
 * @param name variable name
 * @param dataType a fixed-length datatype.  (NOTE: Should be cloned to program datatype manager
 * prior to determining storage elements since their length may change)
 * @param storage variable storage or null for unassigned storage (may be null)
 * @param storageAddr storage address or null if no storage has been identified (may be null)
 * @param stackOffset signed stack offset (may be null)
 * @param register register storage (may be null)
 * @param force if true storage will be forced even if mismatch with datatype size
 * @param program target program
 * @param sourceType source type
 * @throws InvalidInputException if dataType restrictions are violated or an error occurs while 
 * resolving storage for specified datatype
 * @throws AddressOutOfBoundsException if invalid stack offset specified
 */
VariableImpl(String name, DataType dataType, VariableStorage storage, Address storageAddr,
		Integer stackOffset, Register register, boolean force, Program program,
		SourceType sourceType) throws InvalidInputException {

	checkUsage(storage, storageAddr, stackOffset, register);
	checkProgram(program);

	this.program = program;
	this.name = name;

	if (storage == null) {
		if (register != null) {
			this.dataType = VariableUtilities.checkDataType(dataType, false,
				register.getMinimumByteSize(), program);
			int size = this.dataType.getLength();
			storageAddr = register.getAddress();
			int regSize = register.getMinimumByteSize();
			if (regSize < size) { // datatype larger than register
				if (!force) {
					throw new InvalidInputException("Register '" + register.getName() +
						"' size too small for specified data type size: " +
						dataType.getLength());
				}
				// allow size mismatch if forced and bypass normal storage computation
				this.variableStorage = new VariableStorage(program, register);
				return;
			}
			else if (register.isBigEndian() && regSize > size) {
				storageAddr = storageAddr.add(regSize - size);
			}
		}
		else {
			if (stackOffset != null) {
				storageAddr =
					program.getAddressFactory().getStackSpace().getAddress(stackOffset);
			}
			this.dataType = VariableUtilities.checkDataType(dataType,
				storageAddr == null && isVoidAllowed(), 1, program);
		}
		this.variableStorage = computeStorage(storageAddr);
	}
	else {
		this.dataType = VariableUtilities.checkDataType(dataType,
			(storage.isVoidStorage() || storage.isUnassignedStorage()) && isVoidAllowed(),
			storage.size(), program);
		VariableUtilities.checkStorage(storage, this.dataType, force);
		this.variableStorage = storage;
	}

	this.sourceType = hasDefaultName() ? SourceType.DEFAULT : sourceType;
}
 
Example 12
Source File: Pic17c7xxAnalyzer.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
 * Attempt to markup FReg access instruction with register reference.
 * 
 * @param instr
 * @return register name if identified, else null
 */
private String markupFRegInstruction(Instruction instr, int opIndex, RefType refType) {
	Object[] objs = instr.getOpObjects(opIndex);
	if (objs.length != 1) {
		return null;
	}

	Address addr;
	Register reg = null;
	if (objs[0] instanceof Register) {
		return ((Register) objs[0]).getName();
	}
	else if (objs[0] instanceof Address) {
		addr = (Address) objs[0];
		reg = program.getRegister(addr, 1);
	}
	else if (objs[0] instanceof Scalar) {
		long offset = ((Scalar) objs[0]).getUnsignedValue();
		long bank = 0;
		if (offset >= 0x10 && offset <= 0x17) {
			if (!bsrContext.hasValue()) {
				return null;
			}
			bank = bsrContext.longValue() & 0x0f;
		}
		else if (offset >= 0x20) {
			if (!bsrContext.hasValue()) {
				return null;
			}
			bank = bsrContext.longValue() >> 4;
		}
		offset += bank << 8;
		addr = program.getAddressFactory().getAddressSpace("DATA").getAddress(offset);
		reg = program.getRegister(addr);
	}
	else {
		return null;
	}

	// Determine RefType
	if (refType == null) {
		refType = RefType.READ;
		String mnemonic = instr.getMnemonicString();
		if ("CLRF".equals(mnemonic) || "MOVWF".equals(mnemonic)) {
			refType = RefType.WRITE;
		}
		else if (FREG_BIT_INSTRUCTIONS.contains(mnemonic)) {
			if ("BCF".equals(mnemonic) || "BSF".equals(mnemonic)) {
				refType = RefType.READ_WRITE;
			}
		}
		else if (opIndex == 0 && instr.getNumOperands() == 2) {
			List<?> repObjs = instr.getDefaultOperandRepresentationList(1);
			if (repObjs.size() == 1 && DEST_FREG.equals(repObjs.get(0))) {
				refType = RefType.READ_WRITE;
			}
		}
	}

	if (addr.isMemoryAddress()) {
		refMgr.addMemoryReference(instr.getMinAddress(), addr, refType, SourceType.ANALYSIS,
			opIndex);
	}

	return reg != null ? reg.getName() : null;
}
 
Example 13
Source File: DatabaseRangeMapAdapter.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
 * @see ghidra.program.util.RangeMapAdapter#setLanguage(ghidra.program.util.LanguageTranslator, ghidra.program.model.lang.Register, ghidra.util.task.TaskMonitor)
 */
@Override
public void setLanguage(LanguageTranslator translator, Register mapReg, TaskMonitor monitor)
		throws CancelledException {

	Register newReg = translator.getNewRegister(mapReg);
	if (newReg == null) {
		// register not translated - clear map
		rangeMap.dispose();
		rangeMap = null;
		return;
	}
	Register newBaseReg = newReg.getBaseRegister();

	AddressRangeMapDB tempMap = null;
	if (!newReg.isBaseRegister() || translator.isValueTranslationRequired(mapReg)) {

		// Create temporary map
		String tempName = "TEMP_MAP";
		int retry = 0;
		while (AddressRangeMapDB.exists(dbh, tempName)) {
			tempName = "TEMP_MAP" + (++retry);
		}
		tempMap =
			new AddressRangeMapDB(dbh, addressMap, new Lock("Test"), tempName, errorHandler,
				BinaryField.class, false);

		// Translate range map data into tempMap
		monitor.initialize(rangeMap.getRecordCount());
		monitor.setMessage("Converting " + mapReg.getName() + " values...");
		int cnt = 0;
		AddressRangeIterator rangeIter = rangeMap.getAddressRanges();
		while (rangeIter.hasNext()) {
			if (monitor.isCancelled()) {
				tempMap.dispose();
				throw new CancelledException();
			}
			AddressRange range = rangeIter.next();
			BinaryField value = (BinaryField) rangeMap.getValue(range.getMinAddress());
			byte[] oldBytes = value.getBinaryData();
			RegisterValue regValue = new RegisterValue(mapReg, oldBytes);
			regValue = translator.getNewRegisterValue(regValue);
			if (regValue != null && regValue.hasAnyValue()) {
				byte[] newBytes = regValue.toBytes();
				tempMap.paintRange(range.getMinAddress(), range.getMaxAddress(),
					new BinaryField(newBytes));
			}
			monitor.setProgress(++cnt);
		}
	}

	String newMapName = NAME_PREFIX + newBaseReg.getName();
	if (tempMap == null) {
		if (mapName.equals(newMapName)) {
			// Nothing to change
			return;
		}
	}
	else {
		rangeMap.dispose();
		rangeMap = tempMap;
	}
	if (rangeMap != null) {
		try {
			rangeMap.setName(newMapName);
		}
		catch (DuplicateNameException e) {
			throw new AssertException("Unexpected DuplicateNameException");
		}
	}
	mapName = newMapName;
}
 
Example 14
Source File: SetRegisterValueDialog.java    From ghidra with Apache License 2.0 4 votes vote down vote up
RegisterWrapper(Register register) {
	this.register = register;
	displayName = register.getName() + " (" + register.getBitLength() + getAliases() + ")";
}
 
Example 15
Source File: ProgramDiffDetails.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
 * Adds the Diff Details for the indicated register to the details document.
 * @param pc1 first program's register context
 * @param pc2 second program's register context
 * @param reg1 the register
 * @throws ConcurrentModificationException if analysis is modifying the program context.
 */
private void addRegisterDiffDetails(ProgramContext pc1, ProgramContext pc2, Register reg1)
		throws ConcurrentModificationException {
	String name = reg1.getName();
	Register reg2 = pc2.getRegister(name);

	AddressRangeIterator p1AddressRangeIter = checkP1AddressSet.getAddressRanges();
	while (p1AddressRangeIter.hasNext()) {
		AddressRange p1Range = p1AddressRangeIter.next();
		Address min1 = p1Range.getMinAddress();
		Address max1 = p1Range.getMaxAddress();
		Address min2 = SimpleDiffUtility.getCompatibleAddress(p1, min1, p2);
		Address max2 = SimpleDiffUtility.getCompatibleAddress(p1, max1, p2);

		AddressRangeIterator it1 = pc1.getRegisterValueAddressRanges(reg1, min1, max1); // Can throw ConcurrentModificationException
		AddressRangeIterator it2 = pc2.getRegisterValueAddressRanges(reg2, min2, max2); // Can throw ConcurrentModificationException

		// CombinedAddressRangeIterator only works for iterators from the same program.
		// So convert the program2 iterator to a program1 iterator and pass it to the constructor.
		AddressRangeIteratorConverter convertedIt2 = new AddressRangeIteratorConverter(it2, p1);
		AddressRangeIterator p1CombinedIterator =
			new CombinedAddressRangeIterator(it1, convertedIt2);

		while (p1CombinedIterator.hasNext()) {
			AddressRange addrRange1 = p1CombinedIterator.next();
			Address rangeMin1 = addrRange1.getMinAddress();
			Address rangeMax1 = addrRange1.getMaxAddress();
			Address rangeMin2 = SimpleDiffUtility.getCompatibleAddress(p1, rangeMin1, p2);
			BigInteger value1 = pc1.getValue(reg1, rangeMin1, false);
			BigInteger value2 = pc2.getValue(reg2, rangeMin2, false);
			boolean sameValue = (value1 == null) ? (value2 == null) : value1.equals(value2);
			if (!sameValue) {
				if (!hasProgramContextDiffs) {
					addDiffHeader("Program Context");
					addDisplayRegValues(null, rangeMin1, rangeMax1, value1, value2);
					hasProgramContextDiffs = true;
				}
				addDisplayRegValues(reg1, rangeMin1, rangeMax1, value1, value2);
			}
		}
	}
}
 
Example 16
Source File: ProgramDiffDetails.java    From ghidra with Apache License 2.0 4 votes vote down vote up
private void addDisplayRegValues(Register reg, Address p1MinRegAddr, Address p1MaxRegAddr,
		BigInteger value1, BigInteger value2) {
	String minStr = p1MinRegAddr.toString();
	String maxStr = p1MaxRegAddr.toString();
	String separatorSpaces = getSpaces(2);

	AddressSpace p1DefaultSpace = p1.getAddressFactory().getDefaultAddressSpace();
	int maxAddrLength = p1DefaultSpace.getMaxAddress().toString().length();
	if (maxAddrLength < 10) {
		maxAddrLength = 10;
	}
	int maxValueLength = Long.toHexString(-1L).length() + 2;
	if (maxValueLength < 14) {
		maxValueLength = 14;
	}

	addText(indent2);
	if (reg == null) {
		// Underline the header.
		underline("Register");
		underline(getSpaces(maxRegisterName - "Register".length()));
		addText(separatorSpaces);
		underline("MinAddress");
		underline(getSpaces(maxAddrLength - "MinAddress".length()));
		addText(separatorSpaces);
		underline("MaxAddress");
		underline(getSpaces(maxAddrLength - "MaxAddress".length()));
		addText(separatorSpaces);
		underline("Program1 Value");
		underline(getSpaces(maxValueLength - "Program1 Value".length()));
		addText(separatorSpaces);
		underline("Program2 Value");
		underline(getSpaces(maxValueLength - "Program2 Value".length()));
	}
	else {
		String regName = reg.getName();
		addColorText(regName);
		addText(getSpaces(maxRegisterName - regName.length()));
		addText(separatorSpaces);
		addColorText(minStr);
		addText(getSpaces(maxAddrLength - minStr.length()));
		addText(separatorSpaces);
		addColorText(maxStr);
		addText(getSpaces(maxAddrLength - maxStr.length()));
		addText(separatorSpaces);
		String value1Str = (value1 != null) ? "0x" + value1.toString(16) : "Undefined";
		addText(getSpaces(maxValueLength - value1Str.length()));
		addColorText(value1Str);
		addText(separatorSpaces);
		String value2Str = (value2 != null) ? "0x" + value2.toString(16) : "Undefined";
		addText(getSpaces(maxValueLength - value2Str.length()));
		addColorText(value2Str);
	}
	addText(newLine);
}
 
Example 17
Source File: Pic18Analyzer.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
	 * Attempt to markup FReg access instruction with register reference.
	 * 
	 * @param instr
	 * @return register name if identified, else null
	 */
	private String markupFRegInstruction(Instruction instr, int opIndex, RefType refType) {
		Object[] objs = instr.getOpObjects(opIndex);
		if (objs.length != 1) {
			return null;
		}

		Address addr;
		Register reg = null;
		if (objs[0] instanceof Register) {
			reg = ((Register) objs[0]);
			addr = reg.getAddress();
		}
		else if (objs[0] instanceof Address) {
			addr = (Address) objs[0];
			reg = program.getRegister(addr, 1);
		}
		else if (objs[0] instanceof Scalar) {

//			long offset = ((Scalar)objs[0]).getUnsignedValue();
//			Object[] accessObjs = instr.getOpObjects(instr.getNumOperands()-1);
//			if (objs.length == 1 && "BANKED".equals(accessObjs[0])) {
//				// BANKED mode
//				if (bsrSetAddr == null || !(objs[0] instanceof Scalar)) {
//					return null;
//				}
//				offset += ((long)(bsrVal & 0x0f) << 8);
//			}
//			else {
//				// ACCESS mode
//				offset = ((Scalar)objs[0]).getUnsignedValue();
//			}

			if (!bsrContext.hasValue() || !(objs[0] instanceof Scalar)) {
				return null;
			}
			long offset =
				((bsrContext.longValue() & 0x0f) << 8) + ((Scalar) objs[0]).getUnsignedValue();
			addr = program.getAddressFactory().getAddressSpace("DATA").getAddress(offset);
			reg = program.getRegister(addr);
		}
		else {
			return null;
		}

		// Determine RefType
		String mnemonic = instr.getMnemonicString();
		if (refType == null) {
			refType = RefType.READ;
			if ("CLRF".equals(mnemonic) || "MOVWF".equals(mnemonic) || "LFSR".equals(mnemonic)) {
				refType = RefType.WRITE;
			}
			else if (FREG_BIT_INSTRUCTIONS.contains(mnemonic)) {
				if ("BCF".equals(mnemonic) || "BSF".equals(mnemonic)) {
					refType = RefType.READ_WRITE;
				}
			}
			else if (opIndex == 0 && instr.getNumOperands() == 3) {
				// Detect read/write update of register
				List<?> repObjs = instr.getDefaultOperandRepresentationList(1);
				if (repObjs.size() == 1 && DEST_FREG.equals(repObjs.get(0))) {
					refType = RefType.READ_WRITE;
				}
			}
		}

		if (stkptrReg.equals(reg)) {
			addr = stkptr0Reg.getAddress();
		}

		if (addr.isMemoryAddress()) {
			refMgr.addMemoryReference(instr.getMinAddress(), addr, refType, SourceType.ANALYSIS,
				opIndex);
		}

		return reg != null ? reg.getName() : null;
	}
 
Example 18
Source File: Pic12Analyzer.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
 * Attempt to markup FReg access instruction with register reference.
 * 
 * @param instr
 * @return register name if identified, else null
 */
private String markupFRegInstruction(Instruction instr) {
	Object[] objs = instr.getOpObjects(0);
	if (objs.length != 1) {
		return null;
	}

	Address addr;
	Register reg = null;
	if (objs[0] instanceof Register) {
		reg = ((Register) objs[0]);
		addr = reg.getAddress();
	}
	else if (objs[0] instanceof Address) {
		addr = (Address) objs[0];
		reg = program.getRegister(addr, 1);
	}
	else if (objs[0] instanceof Scalar) {
		long offset = ((Scalar) objs[0]).getUnsignedValue();
		if ((offset & 0x1f) >= 0x10) {
			if (!fsrContext.hasValue()) {
				return null;
			}
			offset = (fsrContext.longValue() & 0x60) + offset;
		}
		addr = program.getAddressFactory().getAddressSpace("DATA").getAddress(offset);
		reg = program.getRegister(addr);
	}
	else {
		return null;
	}

	// Determine RefType
	String mnemonic = instr.getMnemonicString();
	RefType refType = RefType.READ;
	if ("CLRF".equals(mnemonic) || "MOVWF".equals(mnemonic)) {
		refType = RefType.WRITE;
	}
	else if (FREG_BIT_INSTRUCTIONS.contains(mnemonic)) {
		if ("BCF".equals(mnemonic) || "BSF".equals(mnemonic)) {
			refType = RefType.READ_WRITE;
		}
	}
	else if (instr.getNumOperands() == 2) {
		List<?> repObjs = instr.getDefaultOperandRepresentationList(1);
		if (repObjs.size() == 1 && DEST_FREG.equals(repObjs.get(0))) {
			refType = RefType.READ_WRITE;
		}
	}

	if (statusReg.equals(reg)) {
		addr = status0Reg.getAddress();
	}
	else if (fsrReg.equals(reg)) {
		addr = fsr0Reg.getAddress();
	}
	else if (pclReg.equals(reg)) {
		addr = pcl0Reg.getAddress();
	}

	if (addr.isMemoryAddress()) {
		refMgr.addMemoryReference(instr.getMinAddress(), addr, refType, SourceType.DEFAULT, 0);
	}

	return reg != null ? reg.getName() : null;
}