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 armDisassembleAction;
|
||||
private DockingAction armThumbDisassembleAction;
|
||||
private DockingAction hcs12DisassembleAction;
|
||||
private DockingAction xgateDisassembleAction;
|
||||
private DockingAction mipsDisassembleAction;
|
||||
private DockingAction mips16DisassembleAction;
|
||||
private DockingAction ppcDisassembleAction;
|
||||
|
@ -172,6 +174,8 @@ public class DisassemblerPlugin extends Plugin {
|
|||
contextAction = new ContextAction(this, GROUP_NAME);
|
||||
armDisassembleAction = new ArmDisassembleAction(this, GROUP_NAME, false);
|
||||
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);
|
||||
mips16DisassembleAction = new MipsDisassembleAction(this, GROUP_NAME, true);
|
||||
ppcDisassembleAction = new PowerPCDisassembleAction(this, GROUP_NAME, false);
|
||||
|
@ -183,6 +187,8 @@ public class DisassemblerPlugin extends Plugin {
|
|||
tool.addAction(disassembleStaticAction);
|
||||
tool.addAction(armDisassembleAction);
|
||||
tool.addAction(armThumbDisassembleAction);
|
||||
tool.addAction(hcs12DisassembleAction);
|
||||
tool.addAction(xgateDisassembleAction);
|
||||
tool.addAction(mipsDisassembleAction);
|
||||
tool.addAction(mips16DisassembleAction);
|
||||
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) {
|
||||
ProgramSelection currentSelection = context.getSelection();
|
||||
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