mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-1216 additional refactor from testing and fallout from
Register.NO_CONTEXT returned instead of null
This commit is contained in:
parent
5e0c5ee3fc
commit
1883a9c19c
27 changed files with 189 additions and 184 deletions
|
@ -61,7 +61,7 @@ public class DebuggerTracePcodeEmulator extends TracePcodeEmulator {
|
||||||
protected BytesPcodeThread createThread(String name) {
|
protected BytesPcodeThread createThread(String name) {
|
||||||
BytesPcodeThread thread = super.createThread(name);
|
BytesPcodeThread thread = super.createThread(name);
|
||||||
Register contextreg = language.getContextBaseRegister();
|
Register contextreg = language.getContextBaseRegister();
|
||||||
if (contextreg != null && !isRegisterKnown(name, contextreg)) {
|
if (contextreg != Register.NO_CONTEXT && !isRegisterKnown(name, contextreg)) {
|
||||||
RegisterValue context = trace.getRegisterContextManager()
|
RegisterValue context = trace.getRegisterContextManager()
|
||||||
.getValueWithDefault(language, contextreg, snap, thread.getCounter());
|
.getValueWithDefault(language, contextreg, snap, thread.getCounter());
|
||||||
thread.overrideContext(context);
|
thread.overrideContext(context);
|
||||||
|
@ -71,8 +71,7 @@ public class DebuggerTracePcodeEmulator extends TracePcodeEmulator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PcodeExecutorState<byte[]> createMemoryState() {
|
protected PcodeExecutorState<byte[]> createMemoryState() {
|
||||||
return new ReadsTargetMemoryPcodeExecutorState(tool, trace, snap, null, 0,
|
return new ReadsTargetMemoryPcodeExecutorState(tool, trace, snap, null, 0, recorder);
|
||||||
recorder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.trace.database.listing;
|
package ghidra.trace.database.listing;
|
||||||
|
|
||||||
import static ghidra.lifecycle.Unfinished.TODO;
|
import static ghidra.lifecycle.Unfinished.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
@ -149,7 +149,7 @@ public class DBTraceCodeManager
|
||||||
static RegisterValue getBaseContextValue(Language language, byte[] context,
|
static RegisterValue getBaseContextValue(Language language, byte[] context,
|
||||||
Address address) {
|
Address address) {
|
||||||
Register register = language.getContextBaseRegister();
|
Register register = language.getContextBaseRegister();
|
||||||
if (register == null) {
|
if (register == Register.NO_CONTEXT) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
|
@ -193,8 +193,7 @@ public class DBTraceCodeManager
|
||||||
|
|
||||||
protected final Map<AddressSnap, UndefinedDBTraceData> undefinedCache =
|
protected final Map<AddressSnap, UndefinedDBTraceData> undefinedCache =
|
||||||
CacheBuilder.newBuilder()
|
CacheBuilder.newBuilder()
|
||||||
.removalListener(
|
.removalListener(this::undefinedRemovedFromCache)
|
||||||
this::undefinedRemovedFromCache)
|
|
||||||
.weakValues()
|
.weakValues()
|
||||||
.build()
|
.build()
|
||||||
.asMap();
|
.asMap();
|
||||||
|
@ -356,8 +355,8 @@ public class DBTraceCodeManager
|
||||||
}
|
}
|
||||||
monitor.setMessage("Clearing instruction prototypes");
|
monitor.setMessage("Clearing instruction prototypes");
|
||||||
monitor.setMaximum(protoStore.getRecordCount());
|
monitor.setMaximum(protoStore.getRecordCount());
|
||||||
for (Iterator<DBTraceCodePrototypeEntry> it =
|
for (Iterator<DBTraceCodePrototypeEntry> it = protoStore.asMap().values().iterator(); it
|
||||||
protoStore.asMap().values().iterator(); it.hasNext();) {
|
.hasNext();) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
monitor.incrementProgress(1);
|
monitor.incrementProgress(1);
|
||||||
DBTraceCodePrototypeEntry protoEnt = it.next();
|
DBTraceCodePrototypeEntry protoEnt = it.next();
|
||||||
|
@ -491,9 +490,9 @@ public class DBTraceCodeManager
|
||||||
}
|
}
|
||||||
Collection<AbstractDBTraceCodeUnit<?>> changes = new ArrayList<>();
|
Collection<AbstractDBTraceCodeUnit<?>> changes = new ArrayList<>();
|
||||||
for (DBTraceCodeSpace space : memSpaces.values()) {
|
for (DBTraceCodeSpace space : memSpaces.values()) {
|
||||||
changes.addAll(space.dataMapSpace
|
changes.addAll(
|
||||||
.reduce(TraceAddressSnapRangeQuery.added(from, to, space.space))
|
space.dataMapSpace.reduce(TraceAddressSnapRangeQuery.added(from, to, space.space))
|
||||||
.values());
|
.values());
|
||||||
changes.addAll(space.instructionMapSpace
|
changes.addAll(space.instructionMapSpace
|
||||||
.reduce(TraceAddressSnapRangeQuery.added(from, to, space.space))
|
.reduce(TraceAddressSnapRangeQuery.added(from, to, space.space))
|
||||||
.values());
|
.values());
|
||||||
|
@ -512,9 +511,9 @@ public class DBTraceCodeManager
|
||||||
}
|
}
|
||||||
Collection<AbstractDBTraceCodeUnit<?>> changes = new ArrayList<>();
|
Collection<AbstractDBTraceCodeUnit<?>> changes = new ArrayList<>();
|
||||||
for (DBTraceCodeSpace space : memSpaces.values()) {
|
for (DBTraceCodeSpace space : memSpaces.values()) {
|
||||||
changes.addAll(space.dataMapSpace
|
changes.addAll(
|
||||||
.reduce(TraceAddressSnapRangeQuery.removed(from, to, space.space))
|
space.dataMapSpace.reduce(TraceAddressSnapRangeQuery.removed(from, to, space.space))
|
||||||
.values());
|
.values());
|
||||||
changes.addAll(space.instructionMapSpace
|
changes.addAll(space.instructionMapSpace
|
||||||
.reduce(TraceAddressSnapRangeQuery.removed(from, to, space.space))
|
.reduce(TraceAddressSnapRangeQuery.removed(from, to, space.space))
|
||||||
.values());
|
.values());
|
||||||
|
|
|
@ -296,7 +296,7 @@ public class TracePcodeEmulatorTest extends AbstractGhidraHeadlessIntegrationTes
|
||||||
@Test
|
@Test
|
||||||
public void testIMM() throws Throwable {
|
public void testIMM() throws Throwable {
|
||||||
try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "Toy:BE:64:default")) {
|
try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "Toy:BE:64:default")) {
|
||||||
assertEquals(Register.DEFAULT_CONTEXT, tb.language.getContextBaseRegister());
|
assertEquals(Register.NO_CONTEXT, tb.language.getContextBaseRegister());
|
||||||
|
|
||||||
TraceThread thread = initTrace(tb,
|
TraceThread thread = initTrace(tb,
|
||||||
List.of(
|
List.of(
|
||||||
|
|
|
@ -1196,7 +1196,7 @@ public class DBTraceCodeUnitTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Test with non-default context
|
// TODO: Test with non-default context
|
||||||
assertEquals(Register.DEFAULT_CONTEXT, i4004.getBaseContextRegister());
|
assertEquals(Register.NO_CONTEXT, i4004.getBaseContextRegister());
|
||||||
|
|
||||||
assertEquals(b.language.getRegisters(), i4004.getRegisters());
|
assertEquals(b.language.getRegisters(), i4004.getRegisters());
|
||||||
assertEquals(r4, i4004.getRegister("r4"));
|
assertEquals(r4, i4004.getRegister("r4"));
|
||||||
|
|
|
@ -126,7 +126,7 @@ public class DefaultPcodeThread<T> implements PcodeThread<T> {
|
||||||
this.pc = language.getProgramCounter();
|
this.pc = language.getProgramCounter();
|
||||||
this.contextreg = language.getContextBaseRegister();
|
this.contextreg = language.getContextBaseRegister();
|
||||||
|
|
||||||
if (contextreg != Register.DEFAULT_CONTEXT) {
|
if (contextreg != Register.NO_CONTEXT) {
|
||||||
defaultContext = new ProgramContextImpl(language);
|
defaultContext = new ProgramContextImpl(language);
|
||||||
language.applyContextSettings(defaultContext);
|
language.applyContextSettings(defaultContext);
|
||||||
this.context = defaultContext.getDefaultDisassemblyContext();
|
this.context = defaultContext.getDefaultDisassemblyContext();
|
||||||
|
@ -190,7 +190,7 @@ public class DefaultPcodeThread<T> implements PcodeThread<T> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void overrideContextWithDefault() {
|
public void overrideContextWithDefault() {
|
||||||
if (contextreg != Register.DEFAULT_CONTEXT) {
|
if (contextreg != Register.NO_CONTEXT) {
|
||||||
overrideContext(defaultContext.getDefaultValue(contextreg, counter));
|
overrideContext(defaultContext.getDefaultValue(contextreg, counter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ public class DefaultPcodeThread<T> implements PcodeThread<T> {
|
||||||
long offset = arithmetic.toConcrete(state.getVar(pc)).longValue();
|
long offset = arithmetic.toConcrete(state.getVar(pc)).longValue();
|
||||||
setCounter(language.getDefaultSpace().getAddress(offset));
|
setCounter(language.getDefaultSpace().getAddress(offset));
|
||||||
|
|
||||||
if (contextreg != Register.DEFAULT_CONTEXT) {
|
if (contextreg != Register.NO_CONTEXT) {
|
||||||
try {
|
try {
|
||||||
BigInteger ctx = arithmetic.toConcrete(state.getVar(contextreg));
|
BigInteger ctx = arithmetic.toConcrete(state.getVar(contextreg));
|
||||||
assignContext(new RegisterValue(contextreg, ctx));
|
assignContext(new RegisterValue(contextreg, ctx));
|
||||||
|
@ -271,7 +271,7 @@ public class DefaultPcodeThread<T> implements PcodeThread<T> {
|
||||||
if (frame.isFallThrough()) {
|
if (frame.isFallThrough()) {
|
||||||
overrideCounter(counter.addWrap(decoder.getLastLengthWithDelays()));
|
overrideCounter(counter.addWrap(decoder.getLastLengthWithDelays()));
|
||||||
}
|
}
|
||||||
if (contextreg != Register.DEFAULT_CONTEXT) {
|
if (contextreg != Register.NO_CONTEXT) {
|
||||||
overrideContext(instruction.getRegisterValue(contextreg));
|
overrideContext(instruction.getRegisterValue(contextreg));
|
||||||
}
|
}
|
||||||
postExecuteInstruction();
|
postExecuteInstruction();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -23,44 +22,48 @@ import ghidra.program.util.LanguageTranslatorAdapter;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
|
|
||||||
|
|
||||||
public class ForceRedisassembly extends GhidraScript {
|
public class ForceRedisassembly extends GhidraScript {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
|
|
||||||
if (currentProgram == null) {
|
if (currentProgram == null) {
|
||||||
Msg.showError(this, null, "No Program Error", "No active program found");
|
Msg.showError(this, null, "No Program Error", "No active program found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ProgramDB program = (ProgramDB)currentProgram;
|
ProgramDB program = (ProgramDB) currentProgram;
|
||||||
|
|
||||||
Language lang = program.getLanguage();
|
Language lang = program.getLanguage();
|
||||||
|
|
||||||
LanguageTranslator translator = new MyLanguageTranslator(lang.getLanguageID(), lang.getVersion());
|
LanguageTranslator translator =
|
||||||
|
new MyLanguageTranslator(lang.getLanguageID(), lang.getVersion());
|
||||||
if (!translator.isValid()) {
|
if (!translator.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
program.setLanguage(translator, program.getCompilerSpec().getCompilerSpecID(), true, monitor);
|
program.setLanguage(translator, program.getCompilerSpec().getCompilerSpecID(), true,
|
||||||
|
monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MyLanguageTranslator extends LanguageTranslatorAdapter {
|
private static class MyLanguageTranslator extends LanguageTranslatorAdapter {
|
||||||
protected MyLanguageTranslator(LanguageID languageId, int version) {
|
protected MyLanguageTranslator(LanguageID languageId, int version) {
|
||||||
super(languageId, version, languageId, version);
|
super(languageId, version, languageId, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
if (super.isValid()) {
|
if (super.isValid()) {
|
||||||
try {
|
try {
|
||||||
validateDefaultSpaceMap();
|
validateDefaultSpaceMap();
|
||||||
} catch (IncompatibleLanguageException e) {
|
}
|
||||||
throw new AssertException();
|
catch (IncompatibleLanguageException e) {
|
||||||
|
throw new AssertException();
|
||||||
}
|
}
|
||||||
Register newContextReg = getNewLanguage().getContextBaseRegister();
|
Register newContextReg = getNewLanguage().getContextBaseRegister();
|
||||||
if (newContextReg != null) {
|
if (newContextReg != Register.NO_CONTEXT) {
|
||||||
Register oldContextReg = getOldLanguage().getContextBaseRegister();
|
Register oldContextReg = getOldLanguage().getContextBaseRegister();
|
||||||
if (oldContextReg == null || !isSameRegisterConstruction(oldContextReg, newContextReg)) {
|
if (oldContextReg != Register.NO_CONTEXT ||
|
||||||
|
!isSameRegisterConstruction(oldContextReg, newContextReg)) {
|
||||||
throw new AssertException();
|
throw new AssertException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,11 +71,12 @@ public class ForceRedisassembly extends GhidraScript {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[" + getOldLanguageID() + " (Version " + getOldVersion() + ")] -> [" +
|
return "[" + getOldLanguageID() + " (Version " + getOldVersion() + ")] -> [" +
|
||||||
getNewLanguageID() + " (Version " + getNewVersion() + ")] {Forced Re-Disassembly Translator}";
|
getNewLanguageID() + " (Version " + getNewVersion() +
|
||||||
|
")] {Forced Re-Disassembly Translator}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,10 +147,10 @@ class CodeUnitMerger extends AbstractListingMerger {
|
||||||
mergeLatest = listingMergeMgr.mergeLatest;
|
mergeLatest = listingMergeMgr.mergeLatest;
|
||||||
mergeOriginal = listingMergeMgr.mergeOriginal;
|
mergeOriginal = listingMergeMgr.mergeOriginal;
|
||||||
|
|
||||||
myResolvedDts = (Map<Long, DataType>) mergeManager.getResolveInformation(
|
myResolvedDts = (Map<Long, DataType>) mergeManager
|
||||||
MergeConstants.RESOLVED_MY_DTS);
|
.getResolveInformation(MergeConstants.RESOLVED_MY_DTS);
|
||||||
origResolvedDts = (Map<Long, DataType>) mergeManager.getResolveInformation(
|
origResolvedDts = (Map<Long, DataType>) mergeManager
|
||||||
MergeConstants.RESOLVED_ORIGINAL_DTS);
|
.getResolveInformation(MergeConstants.RESOLVED_ORIGINAL_DTS);
|
||||||
|
|
||||||
mergedCodeUnits = new AddressSet();
|
mergedCodeUnits = new AddressSet();
|
||||||
|
|
||||||
|
@ -775,7 +775,7 @@ class CodeUnitMerger extends AbstractListingMerger {
|
||||||
// May cause the merge code unit to lose info attached to it, such as references.
|
// May cause the merge code unit to lose info attached to it, such as references.
|
||||||
resultListing.clearCodeUnits(range.getMinAddress(), range.getMaxAddress(), false);
|
resultListing.clearCodeUnits(range.getMinAddress(), range.getMaxAddress(), false);
|
||||||
|
|
||||||
if (contextReg != null) {
|
if (contextReg != Register.NO_CONTEXT) {
|
||||||
// Copy context register value
|
// Copy context register value
|
||||||
mergeProgramContext(resultContext, originContext,
|
mergeProgramContext(resultContext, originContext,
|
||||||
originContext.getBaseContextRegister(), range, monitor);
|
originContext.getBaseContextRegister(), range, monitor);
|
||||||
|
|
|
@ -366,8 +366,8 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand {
|
||||||
// re-parse instruction to regenerate fall-through context
|
// re-parse instruction to regenerate fall-through context
|
||||||
program.getLanguage().parse(instr, context, instr.isInDelaySlot());
|
program.getLanguage().parse(instr, context, instr.isInDelaySlot());
|
||||||
RegisterValue contextValue = context.getFlowContextValue(fallThroughAddr, true);
|
RegisterValue contextValue = context.getFlowContextValue(fallThroughAddr, true);
|
||||||
program.getProgramContext().setRegisterValue(fallThroughAddr, fallThroughAddr,
|
program.getProgramContext()
|
||||||
contextValue);
|
.setRegisterValue(fallThroughAddr, fallThroughAddr, contextValue);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
return;
|
return;
|
||||||
|
@ -413,7 +413,7 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
disassemblePoints.addRange(addr, addr);
|
disassemblePoints.addRange(addr, addr);
|
||||||
if (contextReg != null) {
|
if (contextReg != Register.NO_CONTEXT) {
|
||||||
if (seedContext == null) {
|
if (seedContext == null) {
|
||||||
seedContext = new DisassemblerContextImpl(programContext);
|
seedContext = new DisassemblerContextImpl(programContext);
|
||||||
}
|
}
|
||||||
|
@ -503,7 +503,7 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand {
|
||||||
if (ftAddr != null && (ignoreStart == null || !ftAddr.equals(ignoreStart))) {
|
if (ftAddr != null && (ignoreStart == null || !ftAddr.equals(ignoreStart))) {
|
||||||
// alreadyCleared.addRange(ftAddr, addr);
|
// alreadyCleared.addRange(ftAddr, addr);
|
||||||
disassemblePoints.addRange(ftAddr, ftAddr);
|
disassemblePoints.addRange(ftAddr, ftAddr);
|
||||||
if (contextReg != null) {
|
if (contextReg != Register.NO_CONTEXT) {
|
||||||
if (seedContext == null) {
|
if (seedContext == null) {
|
||||||
seedContext = new DisassemblerContextImpl(programContext);
|
seedContext = new DisassemblerContextImpl(programContext);
|
||||||
}
|
}
|
||||||
|
@ -523,8 +523,9 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand {
|
||||||
// clearSet.add(alreadyCleared);
|
// clearSet.add(alreadyCleared);
|
||||||
|
|
||||||
// Get rid of any bad bookmarks at seed points, will be put back if they are still bad.
|
// Get rid of any bad bookmarks at seed points, will be put back if they are still bad.
|
||||||
program.getBookmarkManager().removeBookmarks(disassemblePoints, BookmarkType.ERROR,
|
program.getBookmarkManager()
|
||||||
Disassembler.ERROR_BOOKMARK_CATEGORY, monitor);
|
.removeBookmarks(disassemblePoints, BookmarkType.ERROR,
|
||||||
|
Disassembler.ERROR_BOOKMARK_CATEGORY, monitor);
|
||||||
|
|
||||||
// Disassemble fallthrough reference points
|
// Disassemble fallthrough reference points
|
||||||
DisassembleCommand cmd = new DisassembleCommand(disassemblePoints, null);
|
DisassembleCommand cmd = new DisassembleCommand(disassemblePoints, null);
|
||||||
|
@ -651,9 +652,10 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand {
|
||||||
if (protectedSet.contains(fromBlock.getMinAddress())) {
|
if (protectedSet.contains(fromBlock.getMinAddress())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fromBlock = adjustBlockForSplitProtectedBlock(program, blockModel, fromBlock.getFirstStartAddress(), fromBlock);
|
fromBlock = adjustBlockForSplitProtectedBlock(program, blockModel,
|
||||||
|
fromBlock.getFirstStartAddress(), fromBlock);
|
||||||
|
|
||||||
// HOT SPOT - getDestinations()
|
// HOT SPOT - getDestinations()
|
||||||
CodeBlockReferenceIterator blockRefIter = fromBlock.getDestinations(monitor);
|
CodeBlockReferenceIterator blockRefIter = fromBlock.getDestinations(monitor);
|
||||||
if (clearOffcut) {
|
if (clearOffcut) {
|
||||||
findDestAddrs(fromBlock, destAddrs); // Needed for detecting offcut flows
|
findDestAddrs(fromBlock, destAddrs); // Needed for detecting offcut flows
|
||||||
|
@ -661,7 +663,7 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand {
|
||||||
while (blockRefIter.hasNext()) {
|
while (blockRefIter.hasNext()) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
CodeBlockReference cbRef = blockRefIter.next();
|
CodeBlockReference cbRef = blockRefIter.next();
|
||||||
|
|
||||||
Address blockAddr = cbRef.getReference();
|
Address blockAddr = cbRef.getReference();
|
||||||
if (protectedSet.contains(blockAddr)) {
|
if (protectedSet.contains(blockAddr)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -671,7 +673,8 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand {
|
||||||
}
|
}
|
||||||
CodeBlock destBlock = cbRef.getDestinationBlock();
|
CodeBlock destBlock = cbRef.getDestinationBlock();
|
||||||
if (blockAddr.equals(destBlock.getFirstStartAddress())) {
|
if (blockAddr.equals(destBlock.getFirstStartAddress())) {
|
||||||
destBlock = adjustBlockForSplitProtectedBlock(program, blockModel, blockAddr, destBlock);
|
destBlock = adjustBlockForSplitProtectedBlock(program, blockModel, blockAddr,
|
||||||
|
destBlock);
|
||||||
}
|
}
|
||||||
if (neverSnipStartBlock && destBlock.equals(startBlock)) {
|
if (neverSnipStartBlock && destBlock.equals(startBlock)) {
|
||||||
continue; // do not allow incoming edges to startBlock vertex
|
continue; // do not allow incoming edges to startBlock vertex
|
||||||
|
@ -696,13 +699,13 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: check disassembly hint
|
// TODO: check disassembly hint
|
||||||
blockSet.add(destBlock);
|
blockSet.add(destBlock);
|
||||||
destVertex = new BlockVertex(destBlock);
|
destVertex = new BlockVertex(destBlock);
|
||||||
vertexMap.put(blockAddr, destVertex);
|
vertexMap.put(blockAddr, destVertex);
|
||||||
todoVertices.push(destVertex);
|
todoVertices.push(destVertex);
|
||||||
}
|
}
|
||||||
// HOT SPOT - HashSet.add()
|
// HOT SPOT - HashSet.add()
|
||||||
fromVertex.destVertices.add(destVertex);
|
fromVertex.destVertices.add(destVertex);
|
||||||
destVertex.srcVertices.add(fromVertex);
|
destVertex.srcVertices.add(fromVertex);
|
||||||
}
|
}
|
||||||
|
@ -767,8 +770,8 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand {
|
||||||
return blockSet;
|
return blockSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeBlock adjustBlockForSplitProtectedBlock(Program program, SimpleBlockModel blockModel, Address blockAddr,
|
private CodeBlock adjustBlockForSplitProtectedBlock(Program program,
|
||||||
CodeBlock blockToAdjust) {
|
SimpleBlockModel blockModel, Address blockAddr, CodeBlock blockToAdjust) {
|
||||||
if (!protectedSet.isEmpty()) {
|
if (!protectedSet.isEmpty()) {
|
||||||
AddressSet intersect = protectedSet.intersectRange(blockToAdjust.getMinAddress(),
|
AddressSet intersect = protectedSet.intersectRange(blockToAdjust.getMinAddress(),
|
||||||
blockToAdjust.getMaxAddress());
|
blockToAdjust.getMaxAddress());
|
||||||
|
@ -857,8 +860,9 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand {
|
||||||
public static void clearBadBookmarks(Program program, Address start, Address end,
|
public static void clearBadBookmarks(Program program, Address start, Address end,
|
||||||
TaskMonitor monitor) throws CancelledException {
|
TaskMonitor monitor) throws CancelledException {
|
||||||
AddressSet set = new AddressSet(start, end);
|
AddressSet set = new AddressSet(start, end);
|
||||||
program.getBookmarkManager().removeBookmarks(set, BookmarkType.ERROR,
|
program.getBookmarkManager()
|
||||||
Disassembler.ERROR_BOOKMARK_CATEGORY, monitor);
|
.removeBookmarks(set, BookmarkType.ERROR, Disassembler.ERROR_BOOKMARK_CATEGORY,
|
||||||
|
monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearBadBookmarks(Program program, AddressSetView set, TaskMonitor monitor)
|
public static void clearBadBookmarks(Program program, AddressSetView set, TaskMonitor monitor)
|
||||||
|
|
|
@ -149,15 +149,12 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Options options = program.getOptions(Program.DISASSEMBLER_PROPERTIES);
|
Options options = program.getOptions(Program.DISASSEMBLER_PROPERTIES);
|
||||||
options.registerOption(Disassembler.MARK_BAD_INSTRUCTION_PROPERTY, true,
|
options.registerOption(Disassembler.MARK_BAD_INSTRUCTION_PROPERTY, true, null,
|
||||||
null, "Place ERROR Bookmark at locations where disassembly could not be perfomed.");
|
"Place ERROR Bookmark at locations where disassembly could not be perfomed.");
|
||||||
options.registerOption(
|
options.registerOption(Disassembler.MARK_UNIMPL_PCODE_PROPERTY, true, null,
|
||||||
Disassembler.MARK_UNIMPL_PCODE_PROPERTY,
|
|
||||||
true,
|
|
||||||
null,
|
|
||||||
"Place WARNING Bookmark at locations where a disassembled instruction has unimplemented pcode.");
|
"Place WARNING Bookmark at locations where a disassembled instruction has unimplemented pcode.");
|
||||||
options.registerOption(Disassembler.RESTRICT_DISASSEMBLY_TO_EXECUTE_MEMORY_PROPERTY,
|
options.registerOption(Disassembler.RESTRICT_DISASSEMBLY_TO_EXECUTE_MEMORY_PROPERTY, false,
|
||||||
false, null, "Restrict disassembly to executable memory blocks.");
|
null, "Restrict disassembly to executable memory blocks.");
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
@ -179,7 +176,7 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
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);
|
||||||
ppcVleDisassembleAction= new PowerPCDisassembleAction(this, GROUP_NAME, true);
|
ppcVleDisassembleAction = new PowerPCDisassembleAction(this, GROUP_NAME, true);
|
||||||
setFlowOverrideAction = new SetFlowOverrideAction(this, GROUP_NAME);
|
setFlowOverrideAction = new SetFlowOverrideAction(this, GROUP_NAME);
|
||||||
|
|
||||||
tool.addAction(disassembleAction);
|
tool.addAction(disassembleAction);
|
||||||
|
@ -236,8 +233,8 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
Program currentProgram = context.getProgram();
|
Program currentProgram = context.getProgram();
|
||||||
DisassembleCommand cmd = null;
|
DisassembleCommand cmd = null;
|
||||||
|
|
||||||
boolean isDynamicListing =
|
boolean isDynamicListing = (context instanceof CodeViewerActionContext &&
|
||||||
(context instanceof CodeViewerActionContext && ((CodeViewerActionContext) context).isDyanmicListing());
|
((CodeViewerActionContext) context).isDyanmicListing());
|
||||||
|
|
||||||
if ((currentSelection != null) && (!currentSelection.isEmpty())) {
|
if ((currentSelection != null) && (!currentSelection.isEmpty())) {
|
||||||
cmd = new DisassembleCommand(currentSelection, null, true);
|
cmd = new DisassembleCommand(currentSelection, null, true);
|
||||||
|
@ -276,7 +273,8 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean checkDisassemblyEnabled(ListingActionContext context, Address address, boolean followPtr) {
|
boolean checkDisassemblyEnabled(ListingActionContext context, Address address,
|
||||||
|
boolean followPtr) {
|
||||||
ProgramSelection currentSelection = context.getSelection();
|
ProgramSelection currentSelection = context.getSelection();
|
||||||
Program currentProgram = context.getProgram();
|
Program currentProgram = context.getProgram();
|
||||||
if ((currentSelection != null) && (!currentSelection.isEmpty())) {
|
if ((currentSelection != null) && (!currentSelection.isEmpty())) {
|
||||||
|
@ -304,7 +302,7 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
public void setDefaultContext(ListingActionContext context) {
|
public void setDefaultContext(ListingActionContext context) {
|
||||||
Program contextProgram = context.getProgram();
|
Program contextProgram = context.getProgram();
|
||||||
Register baseContextReg = contextProgram.getLanguage().getContextBaseRegister();
|
Register baseContextReg = contextProgram.getLanguage().getContextBaseRegister();
|
||||||
if (baseContextReg != null && baseContextReg.hasChildren()) {
|
if (baseContextReg != Register.NO_CONTEXT && baseContextReg.hasChildren()) {
|
||||||
tool.showDialog(new ProcessorStateDialog(contextProgram.getProgramContext()),
|
tool.showDialog(new ProcessorStateDialog(contextProgram.getProgramContext()),
|
||||||
context.getComponentProvider());
|
context.getComponentProvider());
|
||||||
}
|
}
|
||||||
|
@ -312,7 +310,7 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
|
|
||||||
public boolean hasContextRegisters(Program currentProgram) {
|
public boolean hasContextRegisters(Program currentProgram) {
|
||||||
Register baseContextReg = currentProgram.getLanguage().getContextBaseRegister();
|
Register baseContextReg = currentProgram.getLanguage().getContextBaseRegister();
|
||||||
return baseContextReg != null && baseContextReg.hasChildren();
|
return baseContextReg != Register.NO_CONTEXT && baseContextReg.hasChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disassembleArmCallback(ListingActionContext context, boolean thumbMode) {
|
public void disassembleArmCallback(ListingActionContext context, boolean thumbMode) {
|
||||||
|
@ -338,7 +336,7 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
tool.executeBackgroundCommand(cmd, currentProgram);
|
tool.executeBackgroundCommand(cmd, currentProgram);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disassembleHcs12Callback(ListingActionContext context, boolean xgMode) {
|
public void disassembleHcs12Callback(ListingActionContext context, boolean xgMode) {
|
||||||
ProgramSelection currentSelection = context.getSelection();
|
ProgramSelection currentSelection = context.getSelection();
|
||||||
ProgramLocation currentLocation = context.getLocation();
|
ProgramLocation currentLocation = context.getLocation();
|
||||||
|
@ -362,7 +360,7 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
tool.executeBackgroundCommand(cmd, currentProgram);
|
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();
|
||||||
|
@ -392,7 +390,7 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
ProgramLocation currentLocation = context.getLocation();
|
ProgramLocation currentLocation = context.getLocation();
|
||||||
Program currentProgram = context.getProgram();
|
Program currentProgram = context.getProgram();
|
||||||
PowerPCDisassembleCommand cmd = null;
|
PowerPCDisassembleCommand cmd = null;
|
||||||
|
|
||||||
if ((currentSelection != null) && (!currentSelection.isEmpty())) {
|
if ((currentSelection != null) && (!currentSelection.isEmpty())) {
|
||||||
cmd = new PowerPCDisassembleCommand(currentSelection, null, vle);
|
cmd = new PowerPCDisassembleCommand(currentSelection, null, vle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,10 +66,10 @@ import ghidra.util.xml.GenericXMLOutputter;
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
public class GenerateOldLanguagePlugin extends Plugin implements FrontEndable {
|
public class GenerateOldLanguagePlugin extends Plugin implements FrontEndable {
|
||||||
|
|
||||||
private static final ExtensionFileFilter OLD_LANG_FILTER = new ExtensionFileFilter("lang",
|
private static final ExtensionFileFilter OLD_LANG_FILTER =
|
||||||
"Old Language File");
|
new ExtensionFileFilter("lang", "Old Language File");
|
||||||
private static final ExtensionFileFilter TRANSLATOR_FILTER = new ExtensionFileFilter("trans",
|
private static final ExtensionFileFilter TRANSLATOR_FILTER =
|
||||||
"Simple Translator File");
|
new ExtensionFileFilter("trans", "Simple Translator File");
|
||||||
|
|
||||||
private DockingAction generateOldLanguageAction;
|
private DockingAction generateOldLanguageAction;
|
||||||
private DockingAction generateTranslatorAction;
|
private DockingAction generateTranslatorAction;
|
||||||
|
@ -95,8 +95,8 @@ public class GenerateOldLanguagePlugin extends Plugin implements FrontEndable {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// ACTIONS - auto generated
|
// ACTIONS - auto generated
|
||||||
generateOldLanguageAction.setMenuBarData(new MenuData(new String[] { "File",
|
generateOldLanguageAction.setMenuBarData(new MenuData(
|
||||||
"Generate Old Language File..." }, null, "Language"));
|
new String[] { "File", "Generate Old Language File..." }, null, "Language"));
|
||||||
|
|
||||||
generateOldLanguageAction.setEnabled(true);
|
generateOldLanguageAction.setEnabled(true);
|
||||||
tool.addAction(generateOldLanguageAction);
|
tool.addAction(generateOldLanguageAction);
|
||||||
|
@ -116,8 +116,8 @@ public class GenerateOldLanguagePlugin extends Plugin implements FrontEndable {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// ACTIONS - auto generated
|
// ACTIONS - auto generated
|
||||||
generateTranslatorAction.setMenuBarData(new MenuData(new String[] { "File",
|
generateTranslatorAction.setMenuBarData(new MenuData(
|
||||||
"Generate Simple Language Translator..." }, null, "Language"));
|
new String[] { "File", "Generate Simple Language Translator..." }, null, "Language"));
|
||||||
|
|
||||||
generateTranslatorAction.setEnabled(true);
|
generateTranslatorAction.setEnabled(true);
|
||||||
tool.addAction(generateTranslatorAction);
|
tool.addAction(generateTranslatorAction);
|
||||||
|
@ -176,17 +176,16 @@ public class GenerateOldLanguagePlugin extends Plugin implements FrontEndable {
|
||||||
chooser.setApproveButtonText("Create");
|
chooser.setApproveButtonText("Create");
|
||||||
// there's no single directory; you need to pick it yourself now
|
// there's no single directory; you need to pick it yourself now
|
||||||
// chooser.setCurrentDirectory(LANGUAGE_DIR);
|
// chooser.setCurrentDirectory(LANGUAGE_DIR);
|
||||||
chooser.setCurrentDirectory(Application.getApplicationRootDirectory().getFile(
|
chooser.setCurrentDirectory(
|
||||||
false));
|
Application.getApplicationRootDirectory().getFile(false));
|
||||||
}
|
}
|
||||||
File file = chooser.getSelectedFile(true);
|
File file = chooser.getSelectedFile(true);
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!file.getName().endsWith(OldLanguageFactory.OLD_LANGUAGE_FILE_EXT)) {
|
if (!file.getName().endsWith(OldLanguageFactory.OLD_LANGUAGE_FILE_EXT)) {
|
||||||
file =
|
file = new File(file.getParent(),
|
||||||
new File(file.getParent(), file.getName() +
|
file.getName() + OldLanguageFactory.OLD_LANGUAGE_FILE_EXT);
|
||||||
OldLanguageFactory.OLD_LANGUAGE_FILE_EXT);
|
|
||||||
}
|
}
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
if (OptionDialog.showYesNoDialog(panel, "Confirm Overwrite",
|
if (OptionDialog.showYesNoDialog(panel, "Confirm Overwrite",
|
||||||
|
@ -199,12 +198,11 @@ public class GenerateOldLanguagePlugin extends Plugin implements FrontEndable {
|
||||||
OldLanguageFactory.createOldLanguageFile(lang, file);
|
OldLanguageFactory.createOldLanguageFile(lang, file);
|
||||||
close();
|
close();
|
||||||
|
|
||||||
int resp =
|
int resp = OptionDialog.showYesNoDialog(
|
||||||
OptionDialog.showYesNoDialog(
|
GenerateOldLanguagePlugin.this.tool.getToolFrame(),
|
||||||
GenerateOldLanguagePlugin.this.tool.getToolFrame(),
|
"Create Simple Translator?",
|
||||||
"Create Simple Translator?",
|
"Old language file generated successfully.\n \n" +
|
||||||
"Old language file generated successfully.\n \n"
|
"Would you like to create a simple translator to another language?");
|
||||||
+ "Would you like to create a simple translator to another language?");
|
|
||||||
if (resp == OptionDialog.YES_OPTION) {
|
if (resp == OptionDialog.YES_OPTION) {
|
||||||
GenerateTranslatorDialog translatorDlgProvider =
|
GenerateTranslatorDialog translatorDlgProvider =
|
||||||
new GenerateTranslatorDialog(lang, file);
|
new GenerateTranslatorDialog(lang, file);
|
||||||
|
@ -278,35 +276,33 @@ public class GenerateOldLanguagePlugin extends Plugin implements FrontEndable {
|
||||||
chooser.setApproveButtonText("Create");
|
chooser.setApproveButtonText("Create");
|
||||||
// there's no single directory; you need to pick it yourself now
|
// there's no single directory; you need to pick it yourself now
|
||||||
// chooser.setCurrentDirectory(LANGUAGE_DIR);
|
// chooser.setCurrentDirectory(LANGUAGE_DIR);
|
||||||
chooser.setCurrentDirectory(Application.getApplicationRootDirectory().getFile(
|
chooser.setCurrentDirectory(
|
||||||
false));
|
Application.getApplicationRootDirectory().getFile(false));
|
||||||
}
|
}
|
||||||
transFile = chooser.getSelectedFile(true);
|
transFile = chooser.getSelectedFile(true);
|
||||||
if (transFile == null) {
|
if (transFile == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!transFile.getName().endsWith(
|
if (!transFile.getName()
|
||||||
LanguageTranslatorFactory.LANGUAGE_TRANSLATOR_FILE_EXT)) {
|
.endsWith(LanguageTranslatorFactory.LANGUAGE_TRANSLATOR_FILE_EXT)) {
|
||||||
transFile =
|
transFile = new File(transFile.getParent(), transFile.getName() +
|
||||||
new File(transFile.getParent(), transFile.getName() +
|
LanguageTranslatorFactory.LANGUAGE_TRANSLATOR_FILE_EXT);
|
||||||
LanguageTranslatorFactory.LANGUAGE_TRANSLATOR_FILE_EXT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String filename = GenerateTranslatorDialog.this.oldLangFile.getName();
|
String filename = GenerateTranslatorDialog.this.oldLangFile.getName();
|
||||||
int index = filename.indexOf(OldLanguageFactory.OLD_LANGUAGE_FILE_EXT);
|
int index = filename.indexOf(OldLanguageFactory.OLD_LANGUAGE_FILE_EXT);
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
filename =
|
filename = filename.substring(0, index) +
|
||||||
filename.substring(0, index) +
|
LanguageTranslatorFactory.LANGUAGE_TRANSLATOR_FILE_EXT;
|
||||||
LanguageTranslatorFactory.LANGUAGE_TRANSLATOR_FILE_EXT;
|
|
||||||
}
|
}
|
||||||
transFile =
|
transFile = new File(
|
||||||
new File(GenerateTranslatorDialog.this.oldLangFile.getParentFile(),
|
GenerateTranslatorDialog.this.oldLangFile.getParentFile(), filename);
|
||||||
filename);
|
|
||||||
}
|
}
|
||||||
if (transFile.exists()) {
|
if (transFile.exists()) {
|
||||||
if (OptionDialog.showYesNoDialog(panel, "Confirm Overwrite",
|
if (OptionDialog.showYesNoDialog(panel, "Confirm Overwrite",
|
||||||
"Overwrite file " + transFile.getName() + "?") != OptionDialog.YES_OPTION) {
|
"Overwrite file " + transFile.getName() +
|
||||||
|
"?") != OptionDialog.YES_OPTION) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -353,12 +349,14 @@ public class GenerateOldLanguagePlugin extends Plugin implements FrontEndable {
|
||||||
toLang.setText(newLang.getLanguageID().getIdAsString());
|
toLang.setText(newLang.getLanguageID().getIdAsString());
|
||||||
root.addContent(toLang);
|
root.addContent(toLang);
|
||||||
|
|
||||||
for (CompilerSpecDescription oldCompilerSpecDescription : oldLang.getCompatibleCompilerSpecDescriptions()) {
|
for (CompilerSpecDescription oldCompilerSpecDescription : oldLang
|
||||||
|
.getCompatibleCompilerSpecDescriptions()) {
|
||||||
CompilerSpecID oldCompilerSpecID = oldCompilerSpecDescription.getCompilerSpecID();
|
CompilerSpecID oldCompilerSpecID = oldCompilerSpecDescription.getCompilerSpecID();
|
||||||
String newId;
|
String newId;
|
||||||
try {
|
try {
|
||||||
newId =
|
newId = newLang.getCompilerSpecByID(oldCompilerSpecID)
|
||||||
newLang.getCompilerSpecByID(oldCompilerSpecID).getCompilerSpecID().getIdAsString();
|
.getCompilerSpecID()
|
||||||
|
.getIdAsString();
|
||||||
}
|
}
|
||||||
catch (CompilerSpecNotFoundException e) {
|
catch (CompilerSpecNotFoundException e) {
|
||||||
newId = newLang.getDefaultCompilerSpec().getCompilerSpecID().getIdAsString();
|
newId = newLang.getDefaultCompilerSpec().getCompilerSpecID().getIdAsString();
|
||||||
|
@ -398,16 +396,17 @@ public class GenerateOldLanguagePlugin extends Plugin implements FrontEndable {
|
||||||
Register oldCtx = oldLang.getContextBaseRegister();
|
Register oldCtx = oldLang.getContextBaseRegister();
|
||||||
Register newCtx = newLang.getContextBaseRegister();
|
Register newCtx = newLang.getContextBaseRegister();
|
||||||
boolean contextWarning = false;
|
boolean contextWarning = false;
|
||||||
if (oldCtx != null && defaultTrans.isValueTranslationRequired(oldCtx)) {
|
if (oldCtx != Register.NO_CONTEXT &&
|
||||||
|
defaultTrans.isValueTranslationRequired(oldCtx)) {
|
||||||
contextWarning = true;
|
contextWarning = true;
|
||||||
}
|
}
|
||||||
else if (oldCtx == null && newCtx != null) {
|
else if (oldCtx == Register.NO_CONTEXT && newCtx != Register.NO_CONTEXT) {
|
||||||
contextWarning = true;
|
contextWarning = true;
|
||||||
}
|
}
|
||||||
if (contextWarning) {
|
if (contextWarning) {
|
||||||
Msg.showWarn(getClass(), tool.getToolFrame(), "Translator Warning",
|
Msg.showWarn(getClass(), tool.getToolFrame(), "Translator Warning",
|
||||||
"The new context register differs from the old context!\n"
|
"The new context register differs from the old context!\n" +
|
||||||
+ "A set_context element or custom translator may be required.");
|
"A set_context element or custom translator may be required.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -531,7 +530,8 @@ public class GenerateOldLanguagePlugin extends Plugin implements FrontEndable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<LanguageDescription> getLanguageDescriptions(boolean includeDeprecatedLanguages) {
|
public List<LanguageDescription> getLanguageDescriptions(
|
||||||
|
boolean includeDeprecatedLanguages) {
|
||||||
// Include deprecated languages
|
// Include deprecated languages
|
||||||
List<LanguageDescription> list = new ArrayList<LanguageDescription>();
|
List<LanguageDescription> list = new ArrayList<LanguageDescription>();
|
||||||
list.addAll(langService.getLanguageDescriptions(true));
|
list.addAll(langService.getLanguageDescriptions(true));
|
||||||
|
|
|
@ -474,14 +474,14 @@ public class ProgramMerge implements PropertyVisitor {
|
||||||
Address max = range.getMaxAddress();
|
Address max = range.getMaxAddress();
|
||||||
Instruction instr = listing.getInstructionContaining(min);
|
Instruction instr = listing.getInstructionContaining(min);
|
||||||
if (instr != null) {
|
if (instr != null) {
|
||||||
instructionSet.add(
|
instructionSet
|
||||||
new AddressRangeImpl(instr.getMinAddress(), instr.getMaxAddress()));
|
.add(new AddressRangeImpl(instr.getMinAddress(), instr.getMaxAddress()));
|
||||||
}
|
}
|
||||||
InstructionIterator instIter = listing.getInstructions(new AddressSet(min, max), true);
|
InstructionIterator instIter = listing.getInstructions(new AddressSet(min, max), true);
|
||||||
while (instIter.hasNext()) {
|
while (instIter.hasNext()) {
|
||||||
instr = instIter.next();
|
instr = instIter.next();
|
||||||
instructionSet.add(
|
instructionSet
|
||||||
new AddressRangeImpl(instr.getMinAddress(), instr.getMaxAddress()));
|
.add(new AddressRangeImpl(instr.getMinAddress(), instr.getMaxAddress()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return instructionSet;
|
return instructionSet;
|
||||||
|
@ -563,8 +563,8 @@ public class ProgramMerge implements PropertyVisitor {
|
||||||
resultRange.getMaxAddress(), false);
|
resultRange.getMaxAddress(), false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (resultContextReg != null) {
|
if (resultContextReg != Register.NO_CONTEXT) {
|
||||||
if (originContextReg != null) {
|
if (originContextReg != Register.NO_CONTEXT) {
|
||||||
// Copy context register value
|
// Copy context register value
|
||||||
mergeProgramContext(resultContext, originContext,
|
mergeProgramContext(resultContext, originContext,
|
||||||
originContext.getBaseContextRegister(), newOriginRange, resultRange,
|
originContext.getBaseContextRegister(), newOriginRange, resultRange,
|
||||||
|
@ -759,15 +759,16 @@ public class ProgramMerge implements PropertyVisitor {
|
||||||
DisassemblerContextImpl context = new DisassemblerContextImpl(program.getProgramContext());
|
DisassemblerContextImpl context = new DisassemblerContextImpl(program.getProgramContext());
|
||||||
context.flowStart(addr);
|
context.flowStart(addr);
|
||||||
try {
|
try {
|
||||||
InstructionPrototype proto = program.getLanguage().parse(
|
InstructionPrototype proto = program.getLanguage()
|
||||||
new DumbMemBufferImpl(program.getMemory(), addr), context, false);
|
.parse(new DumbMemBufferImpl(program.getMemory(), addr), context, false);
|
||||||
return resultListing.createInstruction(addr, proto,
|
return resultListing.createInstruction(addr, proto,
|
||||||
new DumbMemBufferImpl(program.getMemory(), addr),
|
new DumbMemBufferImpl(program.getMemory(), addr),
|
||||||
new ProgramProcessorContext(program.getProgramContext(), addr));
|
new ProgramProcessorContext(program.getProgramContext(), addr));
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
program.getBookmarkManager().setBookmark(addr, BookmarkType.ERROR,
|
program.getBookmarkManager()
|
||||||
Disassembler.ERROR_BOOKMARK_CATEGORY, "Diff/Merge applied bad instruction");
|
.setBookmark(addr, BookmarkType.ERROR, Disassembler.ERROR_BOOKMARK_CATEGORY,
|
||||||
|
"Diff/Merge applied bad instruction");
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1251,8 +1252,8 @@ public class ProgramMerge implements PropertyVisitor {
|
||||||
}
|
}
|
||||||
ReferenceManager resultRM = resultProgram.getReferenceManager();
|
ReferenceManager resultRM = resultProgram.getReferenceManager();
|
||||||
Reference[] resultRefs = resultRM.getReferencesFrom(resultCu.getMinAddress(), opIndex);
|
Reference[] resultRefs = resultRM.getReferencesFrom(resultCu.getMinAddress(), opIndex);
|
||||||
Reference[] originRefs = originProgram.getReferenceManager().getReferencesFrom(
|
Reference[] originRefs = originProgram.getReferenceManager()
|
||||||
originCu.getMinAddress(), opIndex);
|
.getReferencesFrom(originCu.getMinAddress(), opIndex);
|
||||||
HashMap<Reference, Reference> resultsToKeep = new HashMap<>(); // key=OriginRef, value=ResultRef
|
HashMap<Reference, Reference> resultsToKeep = new HashMap<>(); // key=OriginRef, value=ResultRef
|
||||||
// Determine the result references to keep that match the origin references.
|
// Determine the result references to keep that match the origin references.
|
||||||
for (Reference originRef : originRefs) {
|
for (Reference originRef : originRefs) {
|
||||||
|
|
|
@ -195,7 +195,7 @@ public class SleighAssembler implements Assembler {
|
||||||
throw new AssemblyError(
|
throw new AssemblyError(
|
||||||
"Context must be fully-specified (full length, no shift, no unknowns)");
|
"Context must be fully-specified (full length, no shift, no unknowns)");
|
||||||
}
|
}
|
||||||
if (lang.getContextBaseRegister() != null &&
|
if (lang.getContextBaseRegister() != Register.NO_CONTEXT &&
|
||||||
ctx.length() < lang.getContextBaseRegister().getMinimumByteSize()) {
|
ctx.length() < lang.getContextBaseRegister().getMinimumByteSize()) {
|
||||||
throw new AssemblyError(
|
throw new AssemblyError(
|
||||||
"Context must be fully-specified (full length, no shift, no unknowns)");
|
"Context must be fully-specified (full length, no shift, no unknowns)");
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class AssemblyDefaultContext implements DisassemblerContext, DefaultProgr
|
||||||
this.lang = lang;
|
this.lang = lang;
|
||||||
this.at = at;
|
this.at = at;
|
||||||
Register ctxreg = lang.getContextBaseRegister();
|
Register ctxreg = lang.getContextBaseRegister();
|
||||||
if (null == ctxreg) {
|
if (ctxreg == Register.NO_CONTEXT) {
|
||||||
this.defctx = AssemblyPatternBlock.nop();
|
this.defctx = AssemblyPatternBlock.nop();
|
||||||
this.curctx = AssemblyPatternBlock.nop();
|
this.curctx = AssemblyPatternBlock.nop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ public class SleighDebugLogger {
|
||||||
|
|
||||||
ContextCache contextCache = new ContextCache();
|
ContextCache contextCache = new ContextCache();
|
||||||
contextBaseRegister = language.getContextBaseRegister();
|
contextBaseRegister = language.getContextBaseRegister();
|
||||||
if (contextBaseRegister != null) {
|
if (contextBaseRegister != Register.NO_CONTEXT) {
|
||||||
contextCache.registerVariable(contextBaseRegister);
|
contextCache.registerVariable(contextBaseRegister);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,8 +101,8 @@ public class Emulate {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void initInstuctionStateModifier() {
|
private void initInstuctionStateModifier() {
|
||||||
String classname = language.getProperty(
|
String classname = language
|
||||||
GhidraLanguagePropertyKeys.EMULATE_INSTRUCTION_STATE_MODIFIER_CLASS);
|
.getProperty(GhidraLanguagePropertyKeys.EMULATE_INSTRUCTION_STATE_MODIFIER_CLASS);
|
||||||
if (classname == null) {
|
if (classname == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,7 @@ public class Emulate {
|
||||||
*/
|
*/
|
||||||
public RegisterValue getContextRegisterValue() {
|
public RegisterValue getContextRegisterValue() {
|
||||||
Register contextReg = language.getContextBaseRegister();
|
Register contextReg = language.getContextBaseRegister();
|
||||||
if (contextReg == null) {
|
if (contextReg == Register.NO_CONTEXT) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (pseudoInstruction != null) {
|
if (pseudoInstruction != null) {
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class EmulateDisassemblerContext implements DisassemblerContext {
|
||||||
|
|
||||||
public void setCurrentAddress(Address addr) {
|
public void setCurrentAddress(Address addr) {
|
||||||
|
|
||||||
if (contextReg == null) {
|
if (contextReg == Register.NO_CONTEXT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RegisterValue partialValue = null;
|
RegisterValue partialValue = null;
|
||||||
|
@ -99,7 +99,7 @@ public class EmulateDisassemblerContext implements DisassemblerContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initContext() {
|
private void initContext() {
|
||||||
if (contextReg == null) {
|
if (contextReg == Register.NO_CONTEXT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
flowingContextRegisterMask = contextReg.getBaseMask().clone();
|
flowingContextRegisterMask = contextReg.getBaseMask().clone();
|
||||||
|
@ -203,8 +203,7 @@ public class EmulateDisassemblerContext implements DisassemblerContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFutureRegisterValue(Address fromAddr, Address toAddr,
|
public void setFutureRegisterValue(Address fromAddr, Address toAddr, RegisterValue value) {
|
||||||
RegisterValue value) {
|
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -819,8 +819,8 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
|
||||||
* @param oldValue the old datatype.
|
* @param oldValue the old datatype.
|
||||||
* @param newValue the new datatype.
|
* @param newValue the new datatype.
|
||||||
*/
|
*/
|
||||||
public void dataTypeChanged(long dataTypeID, int type, boolean isAutoChange,
|
public void dataTypeChanged(long dataTypeID, int type, boolean isAutoChange, Object oldValue,
|
||||||
Object oldValue, Object newValue) {
|
Object newValue) {
|
||||||
// TODO: do not need to record type changes for packed composite change which is in repsonse
|
// TODO: do not need to record type changes for packed composite change which is in repsonse
|
||||||
// to component size or alignment change.
|
// to component size or alignment change.
|
||||||
if (recordChanges && !isAutoChange) {
|
if (recordChanges && !isAutoChange) {
|
||||||
|
@ -2174,7 +2174,7 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
|
||||||
|
|
||||||
ProgramContext context = getProgramContext();
|
ProgramContext context = getProgramContext();
|
||||||
Register contextReg = context.getBaseContextRegister();
|
Register contextReg = context.getBaseContextRegister();
|
||||||
if (contextReg == null) {
|
if (contextReg == Register.NO_CONTEXT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Register thumbBitReg = context.getRegister("TMode");
|
Register thumbBitReg = context.getRegister("TMode");
|
||||||
|
|
|
@ -472,8 +472,11 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
||||||
if (prototype.hasDelaySlots()) {
|
if (prototype.hasDelaySlots()) {
|
||||||
// perform bounds check on entire delay slot instruction group
|
// perform bounds check on entire delay slot instruction group
|
||||||
try {
|
try {
|
||||||
endAddr = startAddr.addNoWrap(prototype.getFallThroughOffset(
|
endAddr =
|
||||||
protoInstr.getInstructionContext())).previous();
|
startAddr
|
||||||
|
.addNoWrap(prototype.getFallThroughOffset(
|
||||||
|
protoInstr.getInstructionContext()))
|
||||||
|
.previous();
|
||||||
}
|
}
|
||||||
catch (AddressOverflowException e) {
|
catch (AddressOverflowException e) {
|
||||||
break;
|
break;
|
||||||
|
@ -553,9 +556,10 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
||||||
InstructionPrototype prototype = lastInstruction.getPrototype();
|
InstructionPrototype prototype = lastInstruction.getPrototype();
|
||||||
if (prototype.hasDelaySlots()) {
|
if (prototype.hasDelaySlots()) {
|
||||||
try {
|
try {
|
||||||
maxAddr = lastInstruction.getAddress().addNoWrap(
|
maxAddr = lastInstruction.getAddress()
|
||||||
prototype.getFallThroughOffset(
|
.addNoWrap(prototype.getFallThroughOffset(
|
||||||
lastInstruction.getInstructionContext())).previous();
|
lastInstruction.getInstructionContext()))
|
||||||
|
.previous();
|
||||||
}
|
}
|
||||||
catch (AddressOverflowException e) {
|
catch (AddressOverflowException e) {
|
||||||
// ignore
|
// ignore
|
||||||
|
@ -630,7 +634,7 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
||||||
prototype = protoMgr.getPrototype(protoID);
|
prototype = protoMgr.getPrototype(protoID);
|
||||||
|
|
||||||
Register contextReg = contextMgr.getBaseContextRegister();
|
Register contextReg = contextMgr.getBaseContextRegister();
|
||||||
if (contextReg != null) {
|
if (contextReg != Register.NO_CONTEXT) {
|
||||||
try {
|
try {
|
||||||
RegisterValue contextValue = context.getRegisterValue(contextReg);
|
RegisterValue contextValue = context.getRegisterValue(contextReg);
|
||||||
Address start = address;
|
Address start = address;
|
||||||
|
@ -2989,8 +2993,8 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
||||||
boolean isFallthrough =
|
boolean isFallthrough =
|
||||||
(flowType.isJump() && flowAddr.equals(inst.getMaxAddress().next()));
|
(flowType.isJump() && flowAddr.equals(inst.getMaxAddress().next()));
|
||||||
if (!isFallthrough) {
|
if (!isFallthrough) {
|
||||||
mnemonicPrimaryRef = addDefaultMemoryReferenceIfMissing(inst, Reference.MNEMONIC,
|
mnemonicPrimaryRef = addDefaultMemoryReferenceIfMissing(inst,
|
||||||
flowAddr, flowType, oldRefList, mnemonicPrimaryRef);
|
Reference.MNEMONIC, flowAddr, flowType, oldRefList, mnemonicPrimaryRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3020,8 +3024,8 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
||||||
* @param operandPrimaryRef current preferred primary reference for operand
|
* @param operandPrimaryRef current preferred primary reference for operand
|
||||||
* @return updated preferred primary address for operand (i.e., operandPrimaryRef)
|
* @return updated preferred primary address for operand (i.e., operandPrimaryRef)
|
||||||
*/
|
*/
|
||||||
private Reference addDefaultMemoryReferenceIfMissing(Instruction inst,
|
private Reference addDefaultMemoryReferenceIfMissing(Instruction inst, int opIndex,
|
||||||
int opIndex, Address refAddr, RefType refType, List<Reference> oldRefList,
|
Address refAddr, RefType refType, List<Reference> oldRefList,
|
||||||
Reference operandPrimaryRef) {
|
Reference operandPrimaryRef) {
|
||||||
|
|
||||||
Reference ref = removeOldReference(oldRefList, refAddr, opIndex, refType);
|
Reference ref = removeOldReference(oldRefList, refAddr, opIndex, refType);
|
||||||
|
|
|
@ -86,10 +86,6 @@ public class OldProgramContextDB implements ProgramContext, DefaultProgramContex
|
||||||
valueMaps = new HashMap<>();
|
valueMaps = new HashMap<>();
|
||||||
|
|
||||||
baseContextRegister = language.getContextBaseRegister();
|
baseContextRegister = language.getContextBaseRegister();
|
||||||
if (baseContextRegister == null) {
|
|
||||||
baseContextRegister = new Register("DEFAULT_CONTEXT", "DEFAULT_CONTEXT",
|
|
||||||
addrMap.getAddressFactory().getRegisterSpace().getAddress(0x0), 4, true, 0);
|
|
||||||
}
|
|
||||||
defaultDisassemblyContext = new RegisterValue(baseContextRegister);
|
defaultDisassemblyContext = new RegisterValue(baseContextRegister);
|
||||||
|
|
||||||
initializeDefaultValues(language);
|
initializeDefaultValues(language);
|
||||||
|
|
|
@ -88,8 +88,7 @@ public class ProgramRegisterContextDB extends AbstractStoredProgramContext imple
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void upgrade(AddressMap addressMapExt, TaskMonitor monitor)
|
private void upgrade(AddressMap addressMapExt, TaskMonitor monitor) throws CancelledException {
|
||||||
throws CancelledException {
|
|
||||||
|
|
||||||
OldProgramContextDB oldContext =
|
OldProgramContextDB oldContext =
|
||||||
new OldProgramContextDB(dbHandle, errorHandler, language, addressMapExt, lock);
|
new OldProgramContextDB(dbHandle, errorHandler, language, addressMapExt, lock);
|
||||||
|
@ -358,7 +357,7 @@ public class ProgramRegisterContextDB extends AbstractStoredProgramContext imple
|
||||||
|
|
||||||
// May need to fill-in blank context areas with a new specified context value
|
// May need to fill-in blank context areas with a new specified context value
|
||||||
Register ctxReg = newLanguage.getContextBaseRegister();
|
Register ctxReg = newLanguage.getContextBaseRegister();
|
||||||
if (ctxReg != null && translator.isValueTranslationRequired(ctxReg)) {
|
if (ctxReg != Register.NO_CONTEXT && translator.isValueTranslationRequired(ctxReg)) {
|
||||||
RegisterValue gapValue = new RegisterValue(ctxReg);
|
RegisterValue gapValue = new RegisterValue(ctxReg);
|
||||||
gapValue = translator.getNewRegisterValue(gapValue);
|
gapValue = translator.getNewRegisterValue(gapValue);
|
||||||
if (gapValue != null && gapValue.hasAnyValue()) {
|
if (gapValue != null && gapValue.hasAnyValue()) {
|
||||||
|
|
|
@ -254,7 +254,7 @@ public interface Language {
|
||||||
/**
|
/**
|
||||||
* Returns processor context base register or null if one has not been defined by the
|
* Returns processor context base register or null if one has not been defined by the
|
||||||
* language.
|
* language.
|
||||||
* @return base context register or null if not defined
|
* @return base context register or Register.NO_CONTEXT if not defined
|
||||||
*/
|
*/
|
||||||
public Register getContextBaseRegister();
|
public Register getContextBaseRegister();
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,9 @@ public class Register implements java.io.Serializable, Comparable<Register> {
|
||||||
/** Register can be used in SIMD operations **/
|
/** Register can be used in SIMD operations **/
|
||||||
public final static int TYPE_VECTOR = 128;
|
public final static int TYPE_VECTOR = 128;
|
||||||
|
|
||||||
public final static Register DEFAULT_CONTEXT =
|
/** Register used to denote NO defined context for a language **/
|
||||||
new Register("DEFAULT_CONTEXT", "DEFAULT_CONTEXT", Address.NO_ADDRESS, 4, true, 0);
|
public final static Register NO_CONTEXT =
|
||||||
|
new Register("NO_CONTEXT", "NO_CONTEXT", Address.NO_ADDRESS, 4, true, 0);
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private String description; // description of the register
|
private String description; // description of the register
|
||||||
|
|
|
@ -127,7 +127,7 @@ public class RegisterManager {
|
||||||
}
|
}
|
||||||
// if there is no context register, force a default one
|
// if there is no context register, force a default one
|
||||||
if (contextBaseRegister == null) {
|
if (contextBaseRegister == null) {
|
||||||
contextBaseRegister = Register.DEFAULT_CONTEXT;
|
contextBaseRegister = Register.NO_CONTEXT;
|
||||||
}
|
}
|
||||||
// handle the register size 0 case;
|
// handle the register size 0 case;
|
||||||
Collections.reverse(registerListSortedBySize);
|
Collections.reverse(registerListSortedBySize);
|
||||||
|
|
|
@ -50,8 +50,8 @@ public class InstructionUtils {
|
||||||
FlowType flowType = instruction.getFlowType();
|
FlowType flowType = instruction.getFlowType();
|
||||||
textBuf.append("\nFlow Type : " + flowType.toString());
|
textBuf.append("\nFlow Type : " + flowType.toString());
|
||||||
FlowOverride flowOverride = instruction.getFlowOverride();
|
FlowOverride flowOverride = instruction.getFlowOverride();
|
||||||
if (flowOverride != FlowOverride.NONE &&
|
if (flowOverride != FlowOverride.NONE && instruction.getPrototype()
|
||||||
instruction.getPrototype().getFlowType(instruction.getInstructionContext()) != flowType) {
|
.getFlowType(instruction.getInstructionContext()) != flowType) {
|
||||||
textBuf.append("\n >>> reflects " + flowOverride + " flow override");
|
textBuf.append("\n >>> reflects " + flowOverride + " flow override");
|
||||||
}
|
}
|
||||||
Address fallAddr = instruction.getFallThrough();
|
Address fallAddr = instruction.getFallThrough();
|
||||||
|
@ -62,20 +62,20 @@ public class InstructionUtils {
|
||||||
textBuf.append("\nDelay slot depth : " + instruction.getDelaySlotDepth() +
|
textBuf.append("\nDelay slot depth : " + instruction.getDelaySlotDepth() +
|
||||||
(instruction.isInDelaySlot() ? " in slot" : ""));
|
(instruction.isInDelaySlot() ? " in slot" : ""));
|
||||||
textBuf.append(
|
textBuf.append(
|
||||||
"\nHash : " + Integer.toHexString(instruction.getPrototype().hashCode())).append(
|
"\nHash : " + Integer.toHexString(instruction.getPrototype().hashCode()))
|
||||||
'\n');
|
.append('\n');
|
||||||
|
|
||||||
textBuf.append("\nInput Objects:\n" +
|
textBuf.append("\nInput Objects:\n" +
|
||||||
getString(getFormatedInstructionObjects(instruction, true), true));
|
getString(getFormatedInstructionObjects(instruction, true), true));
|
||||||
textBuf.append("\nResult Objects:\n" +
|
textBuf.append("\nResult Objects:\n" +
|
||||||
getString(getFormatedInstructionObjects(instruction, false), true));
|
getString(getFormatedInstructionObjects(instruction, false), true));
|
||||||
textBuf.append(
|
textBuf.append(
|
||||||
"\nConstructor Line #'s:\n" + getString(debug.getConstructorLineNumbers(), true)).append(
|
"\nConstructor Line #'s:\n" + getString(debug.getConstructorLineNumbers(), true))
|
||||||
'\n');
|
.append('\n');
|
||||||
textBuf.append("\nByte Length : " + instruction.getLength());
|
textBuf.append("\nByte Length : " + instruction.getLength());
|
||||||
try {
|
try {
|
||||||
textBuf.append("\nInstr Bytes : " +
|
textBuf.append(
|
||||||
SleighDebugLogger.getFormattedBytes(instruction.getBytes()));
|
"\nInstr Bytes : " + SleighDebugLogger.getFormattedBytes(instruction.getBytes()));
|
||||||
textBuf.append("\nMask : " + debug.getFormattedInstructionMask(-1));
|
textBuf.append("\nMask : " + debug.getFormattedInstructionMask(-1));
|
||||||
textBuf.append("\nMasked Bytes: " + debug.getFormattedMaskedValue(-1)).append('\n');
|
textBuf.append("\nMasked Bytes: " + debug.getFormattedMaskedValue(-1)).append('\n');
|
||||||
}
|
}
|
||||||
|
@ -93,10 +93,11 @@ public class InstructionUtils {
|
||||||
* @param instr
|
* @param instr
|
||||||
* @return formatted context data
|
* @return formatted context data
|
||||||
*/
|
*/
|
||||||
public static String getFormattedContextRegisterValueBreakout(Instruction instr, String indent) {
|
public static String getFormattedContextRegisterValueBreakout(Instruction instr,
|
||||||
|
String indent) {
|
||||||
ProgramContext programContext = instr.getProgram().getProgramContext();
|
ProgramContext programContext = instr.getProgram().getProgramContext();
|
||||||
Register contextReg = programContext.getBaseContextRegister();
|
Register contextReg = programContext.getBaseContextRegister();
|
||||||
if (contextReg == null) {
|
if (contextReg == Register.NO_CONTEXT) {
|
||||||
return indent + "[Instruction context not defined]";
|
return indent + "[Instruction context not defined]";
|
||||||
}
|
}
|
||||||
return getFormattedRegisterValueBits(instr.getRegisterValue(contextReg), indent);
|
return getFormattedRegisterValueBits(instr.getRegisterValue(contextReg), indent);
|
||||||
|
|
|
@ -425,9 +425,9 @@ public abstract class LanguageTranslatorAdapter implements LanguageTranslator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Register newContextReg = getNewLanguage().getContextBaseRegister();
|
Register newContextReg = getNewLanguage().getContextBaseRegister();
|
||||||
if (newContextReg != null) {
|
if (newContextReg != Register.NO_CONTEXT) {
|
||||||
Register oldContextReg = getOldLanguage().getContextBaseRegister();
|
Register oldContextReg = getOldLanguage().getContextBaseRegister();
|
||||||
if (oldContextReg == null ||
|
if (oldContextReg == Register.NO_CONTEXT ||
|
||||||
!isSameRegisterConstruction(oldContextReg, newContextReg)) {
|
!isSameRegisterConstruction(oldContextReg, newContextReg)) {
|
||||||
Msg.error(this, "Translator can not map context register: " + this);
|
Msg.error(this, "Translator can not map context register: " + this);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -143,8 +143,8 @@ public class OldLanguageFactory {
|
||||||
langSvc.getLanguageDescription(oldLang.getLanguageID());
|
langSvc.getLanguageDescription(oldLang.getLanguageID());
|
||||||
if (curDescr.getVersion() <= oldDescr.getVersion()) {
|
if (curDescr.getVersion() <= oldDescr.getVersion()) {
|
||||||
// Ignore old versions which are inappropriate
|
// Ignore old versions which are inappropriate
|
||||||
log.warn("WARNING! Ignoring old language spec, version still exists: " +
|
log.warn(
|
||||||
oldLang);
|
"WARNING! Ignoring old language spec, version still exists: " + oldLang);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,8 +208,8 @@ public class OldLanguageFactory {
|
||||||
* @throws IOException if file error occurs
|
* @throws IOException if file error occurs
|
||||||
* @throws LanguageNotFoundException if lang is unknown to DefaultLanguageService
|
* @throws LanguageNotFoundException if lang is unknown to DefaultLanguageService
|
||||||
*/
|
*/
|
||||||
public static void createOldLanguageFile(Language lang, File file) throws IOException,
|
public static void createOldLanguageFile(Language lang, File file)
|
||||||
LanguageNotFoundException {
|
throws IOException, LanguageNotFoundException {
|
||||||
|
|
||||||
LanguageService languageService = DefaultLanguageService.getLanguageService();
|
LanguageService languageService = DefaultLanguageService.getLanguageService();
|
||||||
if (lang instanceof OldLanguage) {
|
if (lang instanceof OldLanguage) {
|
||||||
|
@ -272,7 +272,7 @@ public class OldLanguageFactory {
|
||||||
|
|
||||||
Register contextReg = lang.getContextBaseRegister();
|
Register contextReg = lang.getContextBaseRegister();
|
||||||
Element registersElement = new Element("registers");
|
Element registersElement = new Element("registers");
|
||||||
if (contextReg != null) {
|
if (contextReg != Register.NO_CONTEXT) {
|
||||||
Element ctxElement = getRegisterElement(contextReg);
|
Element ctxElement = getRegisterElement(contextReg);
|
||||||
int contextBitLength = contextReg.getBitLength();
|
int contextBitLength = contextReg.getBitLength();
|
||||||
for (Register bitReg : contextReg.getChildRegisters()) {
|
for (Register bitReg : contextReg.getChildRegisters()) {
|
||||||
|
|
|
@ -160,7 +160,7 @@ class SimpleLanguageTranslator extends LanguageTranslatorAdapter {
|
||||||
return super.getNewRegisterValue(oldRegisterValue);
|
return super.getNewRegisterValue(oldRegisterValue);
|
||||||
}
|
}
|
||||||
Register newContextReg = getNewLanguage().getContextBaseRegister();
|
Register newContextReg = getNewLanguage().getContextBaseRegister();
|
||||||
if (newContextReg == null || (clearAllContext && contextSettings == null)) {
|
if (newContextReg == Register.NO_CONTEXT || (clearAllContext && contextSettings == null)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
RegisterValue newValue = null;
|
RegisterValue newValue = null;
|
||||||
|
@ -220,8 +220,8 @@ class SimpleLanguageTranslator extends LanguageTranslatorAdapter {
|
||||||
LanguagePostUpgradeInstructionHandler.class.getName());
|
LanguagePostUpgradeInstructionHandler.class.getName());
|
||||||
}
|
}
|
||||||
Constructor<?> constructor = handlerClass.getConstructor(new Class<?>[] { Program.class });
|
Constructor<?> constructor = handlerClass.getConstructor(new Class<?>[] { Program.class });
|
||||||
return (LanguagePostUpgradeInstructionHandler) constructor.newInstance(
|
return (LanguagePostUpgradeInstructionHandler) constructor
|
||||||
new Object[] { program });
|
.newInstance(new Object[] { program });
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue