Corrected issue with ARM emulation for older versions with no thumbmode.

This commit is contained in:
ghidorahrex 2021-06-30 10:00:57 -04:00
parent 6962885c3e
commit c3dc05c7bf
4 changed files with 106 additions and 9 deletions

View file

@ -47,6 +47,16 @@ PCodeTest({
'language_id': 'ARM:LE:32:v7', 'language_id': 'ARM:LE:32:v7',
}) })
PCodeTest({
'name': 'ARMv5',
'build_all': 1,
'build_exe': 1,
'qemu_command': 'qemu-arm',
'toolchain': 'ARM/arm-eabi',
'language_id': 'ARM:LE:32:v5',
'ccflags': '-march=armv5 -L %(toolchain_dir)s/lib/gcc/arm-eabi/%(gcc_version)s -lgcc',
})
PCodeTest({ PCodeTest({
'name': 'ARM7', 'name': 'ARM7',
'toolchain': 'ARM/arm-eabi', 'toolchain': 'ARM/arm-eabi',

View file

@ -15,6 +15,8 @@
*/ */
package ghidra.program.emulation; package ghidra.program.emulation;
import java.math.BigInteger;
import ghidra.pcode.emulate.Emulate; import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.emulate.EmulateInstructionStateModifier; import ghidra.pcode.emulate.EmulateInstructionStateModifier;
import ghidra.pcode.emulate.callother.CountLeadingZerosOpBehavior; import ghidra.pcode.emulate.callother.CountLeadingZerosOpBehavior;
@ -24,8 +26,6 @@ import ghidra.program.model.lang.Register;
import ghidra.program.model.lang.RegisterValue; import ghidra.program.model.lang.RegisterValue;
import ghidra.program.model.pcode.PcodeOp; import ghidra.program.model.pcode.PcodeOp;
import java.math.BigInteger;
public class ARMEmulateInstructionStateModifier extends EmulateInstructionStateModifier { public class ARMEmulateInstructionStateModifier extends EmulateInstructionStateModifier {
private Register TModeReg; private Register TModeReg;
@ -38,11 +38,13 @@ public class ARMEmulateInstructionStateModifier extends EmulateInstructionStateM
TModeReg = language.getRegister("TMode"); TModeReg = language.getRegister("TMode");
TBreg = language.getRegister("ISAModeSwitch"); TBreg = language.getRegister("ISAModeSwitch");
if (TModeReg != null && TBreg == null) { if (TModeReg != null && TBreg == null) {
throw new RuntimeException("Expected language " + language.getLanguageID() + throw new RuntimeException(
" to have TB register defined"); "Expected language " + language.getLanguageID() + " to have TB register defined");
}
if (TModeReg != null) {
tMode = new RegisterValue(TModeReg, BigInteger.ONE);
aMode = new RegisterValue(TModeReg, BigInteger.ZERO);
} }
tMode = new RegisterValue(TModeReg, BigInteger.ONE);
aMode = new RegisterValue(TModeReg, BigInteger.ZERO);
registerPcodeOpBehavior("count_leading_zeroes", new CountLeadingZerosOpBehavior()); registerPcodeOpBehavior("count_leading_zeroes", new CountLeadingZerosOpBehavior());
@ -114,17 +116,22 @@ public class ARMEmulateInstructionStateModifier extends EmulateInstructionStateM
* Initialize TB register based upon context-register state before first instruction is executed. * Initialize TB register based upon context-register state before first instruction is executed.
*/ */
@Override @Override
public void initialExecuteCallback(Emulate emulate, Address current_address, RegisterValue contextRegisterValue) throws LowlevelError { public void initialExecuteCallback(Emulate emulate, Address current_address,
RegisterValue contextRegisterValue) throws LowlevelError {
BigInteger tModeValue = BigInteger.ZERO; BigInteger tModeValue = BigInteger.ZERO;
if (TModeReg == null) {
return;
}
if (contextRegisterValue != null) { if (contextRegisterValue != null) {
tModeValue = contextRegisterValue.getRegisterValue(TModeReg).getUnsignedValueIgnoreMask(); tModeValue =
contextRegisterValue.getRegisterValue(TModeReg).getUnsignedValueIgnoreMask();
} }
if (!BigInteger.ZERO.equals(tModeValue)) { if (!BigInteger.ZERO.equals(tModeValue)) {
tModeValue = BigInteger.ONE; tModeValue = BigInteger.ONE;
} }
emu.getMemoryState().setValue(TBreg, tModeValue); emu.getMemoryState().setValue(TBreg, tModeValue);
} }
/** /**
* Handle odd addresses which may occur when jumping/returning indirectly * Handle odd addresses which may occur when jumping/returning indirectly
* to Thumb mode. It is assumed that language will properly handle * to Thumb mode. It is assumed that language will properly handle

View file

@ -0,0 +1,40 @@
/* ###
* 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.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class ARMv5_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "ARM:LE:32:v5";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public ARMv5_O0_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "ARMv5_GCC_O0";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(ARM_O0_EmulatorTest.class);
}
}

View file

@ -0,0 +1,40 @@
/* ###
* 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.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class ARMv5_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "ARM:LE:32:v5";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public ARMv5_O3_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "ARMv5_GCC_O3";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(ARM_O3_EmulatorTest.class);
}
}