mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Added XGate/HCS12 Disassemble Action command.
This commit is contained in:
parent
b107aa233b
commit
d7934eaafc
3 changed files with 255 additions and 0 deletions
|
@ -0,0 +1,141 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.cmd.disassemble;
|
||||||
|
|
||||||
|
import ghidra.framework.model.DomainObject;
|
||||||
|
import ghidra.program.disassemble.DisassemblerContextImpl;
|
||||||
|
import ghidra.program.model.address.*;
|
||||||
|
import ghidra.program.model.lang.Register;
|
||||||
|
import ghidra.program.model.lang.RegisterValue;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.util.exception.CancelledException;
|
||||||
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command object for performing HCS12/XGate disassembly
|
||||||
|
*/
|
||||||
|
public class Hcs12DisassembleCommand extends DisassembleCommand {
|
||||||
|
|
||||||
|
private boolean xgMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for Hcs12DisassembleCommand.
|
||||||
|
* @param startSet set of addresses to be the start of a disassembly. The
|
||||||
|
* Command object will attempt to start a disassembly at each address in this set.
|
||||||
|
* @param restrictedSet addresses that can be disassembled.
|
||||||
|
* a null set implies no restrictions
|
||||||
|
* @param xgMode pass true if the disassembling in XGATE Mode
|
||||||
|
*/
|
||||||
|
public Hcs12DisassembleCommand(AddressSetView startSet, AddressSetView restrictedSet,
|
||||||
|
boolean xgMode) {
|
||||||
|
super("Disassemble " + (xgMode ? "XGate" : "HCS12"), startSet, restrictedSet, true);
|
||||||
|
this.xgMode = xgMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for DisassembleCommand.
|
||||||
|
* @param startSet set of addresses to be the start of a disassembly. The
|
||||||
|
* Command object will attempt to start a disassembly at each address in this set.
|
||||||
|
* @param restrictedSet addresses that can be disassembled.
|
||||||
|
* a null set implies no restrictions
|
||||||
|
* @param xgMode pass true if the disassembling in XGATE Mode
|
||||||
|
*/
|
||||||
|
public Hcs12DisassembleCommand(Address start, AddressSetView restrictedSet, boolean xgMode) {
|
||||||
|
this(new AddressSet(start, start), restrictedSet, xgMode);
|
||||||
|
useDefaultRepeatPatternBehavior = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSeedContext(DisassemblerContextImpl seedContext) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInitialContext(RegisterValue initialContextValue) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) {
|
||||||
|
Program program = (Program) obj;
|
||||||
|
|
||||||
|
disassemblyPerformed = false;
|
||||||
|
unalignedStart = false;
|
||||||
|
|
||||||
|
// get the XGATE mode register and set accordingly
|
||||||
|
Register xgmodeReg = program.getProgramContext().getRegister("XGATE");
|
||||||
|
RegisterValue xgmodeValue = null;
|
||||||
|
|
||||||
|
// if doing xgate, and have no XGmode reg, no way to do disassemble in xgate
|
||||||
|
if (xgmodeReg == null) {
|
||||||
|
if (xgMode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xgmodeValue = new RegisterValue(xgmodeReg, BigInteger.valueOf(xgMode ? 0x1 : 0x0));
|
||||||
|
super.setInitialContext(xgmodeValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
int alignment = 1;
|
||||||
|
|
||||||
|
// Set XGate Mode context on undefined code units only
|
||||||
|
try {
|
||||||
|
if (startSet != null) {
|
||||||
|
|
||||||
|
// Align startSet so that context only affected at possible instruction starts
|
||||||
|
|
||||||
|
AddressSet alignedSet = new AddressSet();
|
||||||
|
for (AddressRange range : startSet) {
|
||||||
|
Address min = range.getMinAddress();
|
||||||
|
long minOfffset = min.getOffset();
|
||||||
|
if (minOfffset != min.getOffset()) {
|
||||||
|
min = min.getNewAddress(minOfffset);
|
||||||
|
}
|
||||||
|
Address max = range.getMaxAddress();
|
||||||
|
long maxOffset = max.getOffset();
|
||||||
|
if (maxOffset < minOfffset) {
|
||||||
|
// skip short unaligned range
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (maxOffset != max.getOffset()) {
|
||||||
|
max = max.getNewAddress(maxOffset);
|
||||||
|
}
|
||||||
|
alignedSet.addRange(min, max);
|
||||||
|
}
|
||||||
|
if (alignedSet.isEmpty()) {
|
||||||
|
unalignedStart = true;
|
||||||
|
return false; // alignedSet does not contain any aligned starts
|
||||||
|
}
|
||||||
|
startSet = program.getListing().getUndefinedRanges(alignedSet, true, monitor);
|
||||||
|
if (startSet.isEmpty()) {
|
||||||
|
return true; // startSet does not contain any aligned undefined starts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (CancelledException e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return doDisassembly(monitor, program, alignment);
|
||||||
|
}
|
||||||
|
}
|
|
@ -83,6 +83,8 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
private DockingAction contextAction;
|
private DockingAction contextAction;
|
||||||
private DockingAction armDisassembleAction;
|
private DockingAction armDisassembleAction;
|
||||||
private DockingAction armThumbDisassembleAction;
|
private DockingAction armThumbDisassembleAction;
|
||||||
|
private DockingAction hcs12DisassembleAction;
|
||||||
|
private DockingAction xgateDisassembleAction;
|
||||||
private DockingAction mipsDisassembleAction;
|
private DockingAction mipsDisassembleAction;
|
||||||
private DockingAction mips16DisassembleAction;
|
private DockingAction mips16DisassembleAction;
|
||||||
private DockingAction ppcDisassembleAction;
|
private DockingAction ppcDisassembleAction;
|
||||||
|
@ -172,6 +174,8 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
contextAction = new ContextAction(this, GROUP_NAME);
|
contextAction = new ContextAction(this, GROUP_NAME);
|
||||||
armDisassembleAction = new ArmDisassembleAction(this, GROUP_NAME, false);
|
armDisassembleAction = new ArmDisassembleAction(this, GROUP_NAME, false);
|
||||||
armThumbDisassembleAction = new ArmDisassembleAction(this, GROUP_NAME, true);
|
armThumbDisassembleAction = new ArmDisassembleAction(this, GROUP_NAME, true);
|
||||||
|
hcs12DisassembleAction = new Hcs12DisassembleAction(this, GROUP_NAME, false);
|
||||||
|
xgateDisassembleAction = new Hcs12DisassembleAction(this, GROUP_NAME, true);
|
||||||
mipsDisassembleAction = new MipsDisassembleAction(this, GROUP_NAME, false);
|
mipsDisassembleAction = new MipsDisassembleAction(this, GROUP_NAME, false);
|
||||||
mips16DisassembleAction = new MipsDisassembleAction(this, GROUP_NAME, true);
|
mips16DisassembleAction = new MipsDisassembleAction(this, GROUP_NAME, true);
|
||||||
ppcDisassembleAction = new PowerPCDisassembleAction(this, GROUP_NAME, false);
|
ppcDisassembleAction = new PowerPCDisassembleAction(this, GROUP_NAME, false);
|
||||||
|
@ -183,6 +187,8 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
tool.addAction(disassembleStaticAction);
|
tool.addAction(disassembleStaticAction);
|
||||||
tool.addAction(armDisassembleAction);
|
tool.addAction(armDisassembleAction);
|
||||||
tool.addAction(armThumbDisassembleAction);
|
tool.addAction(armThumbDisassembleAction);
|
||||||
|
tool.addAction(hcs12DisassembleAction);
|
||||||
|
tool.addAction(xgateDisassembleAction);
|
||||||
tool.addAction(mipsDisassembleAction);
|
tool.addAction(mipsDisassembleAction);
|
||||||
tool.addAction(mips16DisassembleAction);
|
tool.addAction(mips16DisassembleAction);
|
||||||
tool.addAction(ppcDisassembleAction);
|
tool.addAction(ppcDisassembleAction);
|
||||||
|
@ -350,6 +356,30 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void disassembleHcs12Callback(ListingActionContext context, boolean xgMode) {
|
||||||
|
ProgramSelection currentSelection = context.getSelection();
|
||||||
|
ProgramLocation currentLocation = context.getLocation();
|
||||||
|
Program currentProgram = context.getProgram();
|
||||||
|
Hcs12DisassembleCommand cmd = null;
|
||||||
|
|
||||||
|
if ((currentSelection != null) && (!currentSelection.isEmpty())) {
|
||||||
|
cmd = new Hcs12DisassembleCommand(currentSelection, null, xgMode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Address addr = currentLocation.getAddress();
|
||||||
|
try {
|
||||||
|
currentProgram.getMemory().getByte(addr);
|
||||||
|
cmd = new Hcs12DisassembleCommand(addr, null, xgMode);
|
||||||
|
}
|
||||||
|
catch (MemoryAccessException e) {
|
||||||
|
tool.setStatusInfo("Can't disassemble unitialized memory!", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cmd != null) {
|
||||||
|
tool.executeBackgroundCommand(cmd, currentProgram);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void disassembleMipsCallback(ListingActionContext context, boolean mips16) {
|
public void disassembleMipsCallback(ListingActionContext context, boolean mips16) {
|
||||||
ProgramSelection currentSelection = context.getSelection();
|
ProgramSelection currentSelection = context.getSelection();
|
||||||
ProgramLocation currentLocation = context.getLocation();
|
ProgramLocation currentLocation = context.getLocation();
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.plugin.core.disassembler;
|
||||||
|
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
|
import docking.action.KeyBindingData;
|
||||||
|
import docking.action.MenuData;
|
||||||
|
import ghidra.app.context.ListingActionContext;
|
||||||
|
import ghidra.app.context.ListingContextAction;
|
||||||
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.lang.*;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action for HCS12 mode disassembly
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Hcs12DisassembleAction extends ListingContextAction {
|
||||||
|
private DisassemblerPlugin plugin;
|
||||||
|
private boolean disassembleXgate = false;
|
||||||
|
|
||||||
|
public Hcs12DisassembleAction(DisassemblerPlugin plugin, String groupName, boolean disassembleXgate) {
|
||||||
|
super("Disassemble " + (disassembleXgate ? "HCS12" : "XGate"), plugin.getName());
|
||||||
|
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.disassembleXgate = disassembleXgate;
|
||||||
|
|
||||||
|
setPopupMenuData( new MenuData(
|
||||||
|
new String[]{"Disassemble - "+ (disassembleXgate ? "XGate" : "HCS12") },
|
||||||
|
null,
|
||||||
|
groupName ) );
|
||||||
|
|
||||||
|
int keyEvent = (disassembleXgate ? KeyEvent.VK_F12 : KeyEvent.VK_F11);
|
||||||
|
setKeyBindingData( new KeyBindingData( keyEvent, 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ListingActionContext context) {
|
||||||
|
plugin.disassembleHcs12Callback(context, disassembleXgate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabledForContext(ListingActionContext context) {
|
||||||
|
|
||||||
|
// Action only intended for use where Xgate instructions are available.
|
||||||
|
// The presence of the XGATE context register can be used for this
|
||||||
|
// determination.
|
||||||
|
|
||||||
|
Address address = context.getAddress();
|
||||||
|
if ( address == null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Program program = context.getProgram();
|
||||||
|
Language lang = program.getLanguage();
|
||||||
|
Processor proc = lang.getProcessor();
|
||||||
|
|
||||||
|
if (!"HCS12".equals(proc.toString())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register register = context.getProgram().getProgramContext().getRegister("XGATE");
|
||||||
|
if (register == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin.checkDisassemblyEnabled(context, address, true);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue