mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
514564292f
12 changed files with 223 additions and 34 deletions
|
@ -133,12 +133,13 @@ public class FindNoReturnFunctionsAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
// repair the damage for all non-returning functions
|
// repair the damage for all non-returning functions
|
||||||
if (repairDamageEnabled) {
|
if (repairDamageEnabled) {
|
||||||
AddressSet clearInstSet = new AddressSet();
|
|
||||||
noreturns = noReturnSet.getAddresses(true);
|
noreturns = noReturnSet.getAddresses(true);
|
||||||
for (Address address : noreturns) {
|
for (Address address : noreturns) {
|
||||||
clearInstSet.add(findPotentialDamagedLocations(program, address));
|
AddressSet potentialDamagedLocations = findPotentialDamagedLocations(program, address);
|
||||||
|
|
||||||
|
repairDamagedLocations(monitor, potentialDamagedLocations, noReturnSet);
|
||||||
}
|
}
|
||||||
repairDamagedLocations(monitor, clearInstSet);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -154,14 +155,23 @@ public class FindNoReturnFunctionsAnalyzer extends AbstractAnalyzer {
|
||||||
*
|
*
|
||||||
* @param taskMonitor for cancellation
|
* @param taskMonitor for cancellation
|
||||||
* @param clearInstSet locations to clear and repair
|
* @param clearInstSet locations to clear and repair
|
||||||
|
* @param protectedLocations - locations that should be protected from clearing
|
||||||
*/
|
*/
|
||||||
private void repairDamagedLocations(TaskMonitor taskMonitor, AddressSet clearInstSet) {
|
private void repairDamagedLocations(TaskMonitor taskMonitor, AddressSet clearInstSet, AddressSet protectedLocations) {
|
||||||
if (clearInstSet == null || clearInstSet.isEmpty()) {
|
if (clearInstSet == null || clearInstSet.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AutoAnalysisManager analysisManager = AutoAnalysisManager.getAnalysisManager(program);
|
AutoAnalysisManager analysisManager = AutoAnalysisManager.getAnalysisManager(program);
|
||||||
|
|
||||||
AddressSetView protectedSet = analysisManager.getProtectedLocations();
|
AddressSetView protectedSet = analysisManager.getProtectedLocations();
|
||||||
|
|
||||||
|
protectedSet = protectedSet.union(protectedLocations);
|
||||||
|
|
||||||
|
// TODO: are there other protected locations,
|
||||||
|
// that should never be seeds for locations to be cleared?
|
||||||
|
// For example:
|
||||||
|
// - functions that were marked non-returning by the analyzer.
|
||||||
|
// - locations that are known function start patterns?
|
||||||
|
|
||||||
// entries including data flow referenced from instructions will be repaired
|
// entries including data flow referenced from instructions will be repaired
|
||||||
|
|
||||||
|
@ -243,7 +253,8 @@ public class FindNoReturnFunctionsAnalyzer extends AbstractAnalyzer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find locations that need repairing
|
* Find locations that need repairing. The locations returned are only the
|
||||||
|
* start of a flow that occurs after a call to a non-returning function.
|
||||||
*
|
*
|
||||||
* @param cp current program
|
* @param cp current program
|
||||||
* @param entry non-returning function entry point
|
* @param entry non-returning function entry point
|
||||||
|
@ -280,6 +291,11 @@ public class FindNoReturnFunctionsAnalyzer extends AbstractAnalyzer {
|
||||||
if (fallthruAddr == null) {
|
if (fallthruAddr == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// never add in the entry point that is being marked no return
|
||||||
|
if (fallthruAddr.equals(entry)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// if location right below is an entry point, don't clear it
|
// if location right below is an entry point, don't clear it
|
||||||
Address checkAddr = skipNOPS(fallthruAddr);
|
Address checkAddr = skipNOPS(fallthruAddr);
|
||||||
|
|
|
@ -457,7 +457,7 @@ public class EnumEditorProvider extends ComponentProviderAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyName(Enum newEnuum) {
|
private void applyName(Enum newEnuum) {
|
||||||
String editorName = editorPanel.getEnumName();
|
String editorName = editorPanel.getEnumName().trim();
|
||||||
if (originalEnumName.equals(editorName)) {
|
if (originalEnumName.equals(editorName)) {
|
||||||
return; // nothing to do
|
return; // nothing to do
|
||||||
}
|
}
|
||||||
|
|
|
@ -524,8 +524,8 @@ public class AddEditDialog extends DialogComponentProvider {
|
||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize() {
|
public Dimension getPreferredSize() {
|
||||||
Dimension size = super.getPreferredSize();
|
Dimension size = super.getPreferredSize();
|
||||||
// change the preferred size to use the width determined by the # of columns in
|
// change the preferred size to use the width determined by the # of columns in
|
||||||
// combo box editor instead of the largest item in the combo box data model to
|
// combo box editor instead of the largest item in the combo box data model to
|
||||||
// prevent the dialog from growing huge when a large label gets added to its recent
|
// prevent the dialog from growing huge when a large label gets added to its recent
|
||||||
// items
|
// items
|
||||||
Dimension editorSize = getEditor().getEditorComponent().getPreferredSize();
|
Dimension editorSize = getEditor().getEditorComponent().getPreferredSize();
|
||||||
|
@ -604,7 +604,11 @@ public class AddEditDialog extends DialogComponentProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getText() {
|
private String getText() {
|
||||||
return labelNameChoices.getText();
|
String text = labelNameChoices.getText();
|
||||||
|
if (text != null) {
|
||||||
|
text = text.trim();
|
||||||
|
}
|
||||||
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NamespaceWrapper {
|
public class NamespaceWrapper {
|
||||||
|
|
|
@ -66,6 +66,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
Category cat = program.getListing()
|
Category cat = program.getListing()
|
||||||
.getDataTypeManager()
|
.getDataTypeManager()
|
||||||
.getCategory(new CategoryPath(CategoryPath.ROOT, "Category1"));
|
.getCategory(new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
|
|
||||||
Enum enumm = new EnumDataType("Colors", 1);
|
Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
enumm.add("Green", 0x10);
|
enumm.add("Green", 0x10);
|
||||||
|
@ -102,6 +103,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
Category cat = program.getListing()
|
Category cat = program.getListing()
|
||||||
.getDataTypeManager()
|
.getDataTypeManager()
|
||||||
.getCategory(new CategoryPath(CategoryPath.ROOT, "Category1"));
|
.getCategory(new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
|
|
||||||
Enum enumm = new EnumDataType("Colors", 1);
|
Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
enumm.add("Green", 0x10);
|
enumm.add("Green", 0x10);
|
||||||
|
@ -185,6 +187,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
Category cat = program.getListing()
|
Category cat = program.getListing()
|
||||||
.getDataTypeManager()
|
.getDataTypeManager()
|
||||||
.getCategory(new CategoryPath(CategoryPath.ROOT, "Category1"));
|
.getCategory(new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
|
|
||||||
Enum enumm = new EnumDataType("Colors", 1);
|
Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
enumm.add("Green", 0x10);
|
enumm.add("Green", 0x10);
|
||||||
|
@ -230,6 +233,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
Category cat = program.getListing()
|
Category cat = program.getListing()
|
||||||
.getDataTypeManager()
|
.getDataTypeManager()
|
||||||
.getCategory(new CategoryPath(CategoryPath.ROOT, "Category1"));
|
.getCategory(new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
|
|
||||||
Enum enumm = new EnumDataType("Colors", 1);
|
Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
enumm.add("Green", 0x10);
|
enumm.add("Green", 0x10);
|
||||||
|
@ -484,6 +488,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
Category cat = program.getListing()
|
Category cat = program.getListing()
|
||||||
.getDataTypeManager()
|
.getDataTypeManager()
|
||||||
.getCategory(new CategoryPath(CategoryPath.ROOT, "Category1"));
|
.getCategory(new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
|
|
||||||
Enum enumm = new EnumDataType("Colors", 1);
|
Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
enumm.add("Green", 0x10);
|
enumm.add("Green", 0x10);
|
||||||
|
@ -528,6 +533,48 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNameTrim() throws Exception {
|
||||||
|
|
||||||
|
Enum enummDt = editSampleEnum();
|
||||||
|
|
||||||
|
EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
||||||
|
String newName = " MyNewName ";
|
||||||
|
runSwing(() -> {
|
||||||
|
JTextField nameField = getTextField(panel, "Name");
|
||||||
|
nameField.setText(newName);
|
||||||
|
});
|
||||||
|
|
||||||
|
DockingActionIf applyAction = getAction(plugin, "Apply Enum Changes");
|
||||||
|
assertTrue(applyAction.isEnabled());
|
||||||
|
|
||||||
|
performAction(applyAction);
|
||||||
|
waitForProgram(program);
|
||||||
|
|
||||||
|
assertEquals(newName.trim(), enummDt.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDescriptionTrim() throws Exception {
|
||||||
|
|
||||||
|
Enum enummDt = editSampleEnum();
|
||||||
|
|
||||||
|
EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
||||||
|
String newDescription = " My new description ";
|
||||||
|
runSwing(() -> {
|
||||||
|
JTextField nameField = getTextField(panel, "Description");
|
||||||
|
nameField.setText(newDescription);
|
||||||
|
});
|
||||||
|
|
||||||
|
DockingActionIf applyAction = getAction(plugin, "Apply Enum Changes");
|
||||||
|
assertTrue(applyAction.isEnabled());
|
||||||
|
|
||||||
|
performAction(applyAction);
|
||||||
|
waitForProgram(program);
|
||||||
|
|
||||||
|
assertEquals(newDescription.trim(), enummDt.getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDuplicateValue() throws Exception {
|
public void testDuplicateValue() throws Exception {
|
||||||
|
|
||||||
|
@ -775,8 +822,8 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addEntry(JTable table, EnumTableModel model, String name,
|
private void addEntry(JTable table, EnumTableModel model, String name, long value)
|
||||||
long value) throws Exception {
|
throws Exception {
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
int lastRow = model.getRowCount() - 1;
|
int lastRow = model.getRowCount() - 1;
|
||||||
if (lastRow >= 0) {
|
if (lastRow >= 0) {
|
||||||
|
@ -868,6 +915,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
Category cat = program.getListing()
|
Category cat = program.getListing()
|
||||||
.getDataTypeManager()
|
.getDataTypeManager()
|
||||||
.getCategory(new CategoryPath(CategoryPath.ROOT, "Category1"));
|
.getCategory(new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
|
|
||||||
Enum enumm = new EnumDataType("Colors", 1);
|
Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
enumm.add("Green", 0x10);
|
enumm.add("Green", 0x10);
|
||||||
|
|
|
@ -95,7 +95,7 @@ public class AddEditDialoglTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
dialog.close();
|
close(dialog);
|
||||||
env.dispose();
|
env.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,6 +362,34 @@ public class AddEditDialoglTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertTrue(function.getSymbol().isPrimary());
|
assertTrue(function.getSymbol().isPrimary());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRenameFunction_Trim() throws Exception {
|
||||||
|
|
||||||
|
Symbol s = getUniqueSymbol(program, "entry", null);
|
||||||
|
Function function = program.getFunctionManager().getFunctionAt(s.getAddress());
|
||||||
|
if (function == null) {
|
||||||
|
tool.execute(new CreateFunctionCmd(s.getAddress()), program);
|
||||||
|
program.flushEvents();
|
||||||
|
waitForSwing();
|
||||||
|
function = program.getFunctionManager().getFunctionAt(s.getAddress());
|
||||||
|
s = getUniqueSymbol(program, "entry", null);
|
||||||
|
}
|
||||||
|
// add another label at this address
|
||||||
|
AddLabelCmd cmd = new AddLabelCmd(addr(0x01006420), "fred", SourceType.USER_DEFINED);
|
||||||
|
tool.execute(cmd, program);
|
||||||
|
|
||||||
|
// now attempt to rename the entry label
|
||||||
|
editLabel(s);
|
||||||
|
assertEquals("entry", getText());
|
||||||
|
String newText = " bob ";
|
||||||
|
setText(newText);
|
||||||
|
pressOk();
|
||||||
|
program.flushEvents();
|
||||||
|
waitForSwing();
|
||||||
|
assertEquals("bob", function.getName());
|
||||||
|
assertTrue(function.getSymbol().isPrimary());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetPrimaryOnOtherLabel() throws Exception {
|
public void testSetPrimaryOnOtherLabel() throws Exception {
|
||||||
Symbol s = getUniqueSymbol(program, "entry", null);
|
Symbol s = getUniqueSymbol(program, "entry", null);
|
||||||
|
|
|
@ -15,13 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.program.util;
|
package ghidra.program.util;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.Test;
|
||||||
|
|
||||||
import generic.test.AbstractGenericTest;
|
import generic.test.AbstractGenericTest;
|
||||||
import ghidra.app.plugin.core.analysis.ConstantPropagationAnalyzer;
|
import ghidra.app.plugin.core.analysis.ConstantPropagationAnalyzer;
|
||||||
|
@ -34,6 +32,7 @@ import ghidra.program.model.lang.RegisterValue;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.pcode.Varnode;
|
import ghidra.program.model.pcode.Varnode;
|
||||||
import ghidra.program.model.symbol.Reference;
|
import ghidra.program.model.symbol.Reference;
|
||||||
|
import ghidra.program.model.symbol.ReferenceIterator;
|
||||||
import ghidra.program.util.SymbolicPropogator.Value;
|
import ghidra.program.util.SymbolicPropogator.Value;
|
||||||
import ghidra.util.exception.NotFoundException;
|
import ghidra.util.exception.NotFoundException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
@ -307,6 +306,53 @@ public class ConstantPropogationReferenceTest extends AbstractGenericTest {
|
||||||
assertNoOperandReference(0, instr);
|
assertNoOperandReference(0, instr);
|
||||||
assertOperandReferenceTo(1, instr, addr("0x00040100"));
|
assertOperandReferenceTo(1, instr, addr("0x00040100"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPIC_Call_X86_64() throws Exception {
|
||||||
|
|
||||||
|
builder = new ProgramBuilder("PICCode", ProgramBuilder._X64, "gcc", this);
|
||||||
|
|
||||||
|
// entry
|
||||||
|
// 48 83 ec 28 SUB RSP,0x28
|
||||||
|
// e8 00 00 00 00 CALL LAB_140020119
|
||||||
|
// LAB_140020119
|
||||||
|
// 8f c3 POP RBX
|
||||||
|
// 48 8d 43 e0 LEA RAX,[RBX + -0x20]
|
||||||
|
// ff d0 CALL RAX
|
||||||
|
// 48 83 c4 28 ADD RSP,0x28
|
||||||
|
// c3 RET
|
||||||
|
|
||||||
|
builder.setBytes("0x140020110",
|
||||||
|
"48 83 ec 28 e8 00 00 00 00 8f c3 48 8d 43 e0 ff d0 48 83 c4 28 c3");
|
||||||
|
|
||||||
|
builder.setBytes("0x1400200f9",
|
||||||
|
"15 02 2f 00 00 89 05 e8 b9 00 00 48 83 c4 38");
|
||||||
|
|
||||||
|
builder.disassemble("0x140020110", 21);
|
||||||
|
|
||||||
|
analyzer = new ConstantPropagationAnalyzer();
|
||||||
|
|
||||||
|
program = builder.getProgram();
|
||||||
|
program.startTransaction("Test");
|
||||||
|
|
||||||
|
Address codeStart = addr("140020110");
|
||||||
|
Listing listing = program.getListing();
|
||||||
|
assertNotNull("Bad instruction disassembly", listing.getInstructionAt(codeStart));
|
||||||
|
|
||||||
|
AddressSet addressSet = new AddressSet(codeStart, codeStart.add(21));
|
||||||
|
analyze(addressSet);
|
||||||
|
|
||||||
|
Instruction instr = listing.getInstructionAt(addr("0x140020114"));
|
||||||
|
assertOperandReferenceTo(0, instr, addr("0x140020119"));
|
||||||
|
instr = listing.getInstructionAt(addr("0x140020119"));
|
||||||
|
ReferenceIterator referenceIteratorTo = instr.getReferenceIteratorTo();
|
||||||
|
Reference ref = referenceIteratorTo.next();
|
||||||
|
assertTrue(ref.getReferenceType().isJump());
|
||||||
|
instr = listing.getInstructionAt(addr("0x14002011f"));
|
||||||
|
Reference[] referencesFrom = instr.getReferencesFrom();
|
||||||
|
assertTrue(referencesFrom[0].getReferenceType().isFlow());
|
||||||
|
assertEquals("1400200f9", referencesFrom[0].getToAddress().toString());
|
||||||
|
}
|
||||||
|
|
||||||
private void assertNoOperandReference(int opIndex, Instruction instr) {
|
private void assertNoOperandReference(int opIndex, Instruction instr) {
|
||||||
Reference[] refs = instr.getOperandReferences(opIndex);
|
Reference[] refs = instr.getOperandReferences(opIndex);
|
||||||
|
|
|
@ -1023,6 +1023,28 @@ AddrSpace *ActionConstantPtr::selectInferSpace(Varnode *vn,PcodeOp *op,const vec
|
||||||
return resSpace;
|
return resSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Check if we need to try to infer a constant pointer from the input of the given COPY
|
||||||
|
///
|
||||||
|
/// In general, we do want try, but there is a special case where the COPY feeds into a RETURN and
|
||||||
|
/// the function does \e not return a pointer. We also consider the \b infer_pointers boolean.
|
||||||
|
/// \param op is the given COPY op
|
||||||
|
/// \param data is the function
|
||||||
|
/// \return \b true if we should try to infer
|
||||||
|
bool ActionConstantPtr::checkCopy(PcodeOp *op,Funcdata &data)
|
||||||
|
|
||||||
|
{
|
||||||
|
Varnode *vn = op->getOut();
|
||||||
|
PcodeOp *retOp = vn->loneDescend();
|
||||||
|
if (retOp != (PcodeOp *)0 && retOp->code() == CPUI_RETURN && data.getFuncProto().isOutputLocked()) {
|
||||||
|
type_metatype meta = data.getFuncProto().getOutput()->getType()->getMetatype();
|
||||||
|
if (meta != TYPE_PTR && meta != TYPE_UNKNOWN) {
|
||||||
|
return false; // Do NOT infer, we know the constant can't be pointer
|
||||||
|
}
|
||||||
|
return true; // Try to infer, regardless of infer_pointers config, because we KNOW it is a pointer
|
||||||
|
}
|
||||||
|
return data.getArch()->infer_pointers;
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Determine if given Varnode might be a pointer constant.
|
/// \brief Determine if given Varnode might be a pointer constant.
|
||||||
///
|
///
|
||||||
/// If it is a pointer, return the symbol it points to, or NULL otherwise. If it is determined
|
/// If it is a pointer, return the symbol it points to, or NULL otherwise. If it is determined
|
||||||
|
@ -1054,23 +1076,36 @@ SymbolEntry *ActionConstantPtr::isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op
|
||||||
// Check if the constant is involved in a potential pointer expression
|
// Check if the constant is involved in a potential pointer expression
|
||||||
// as the base
|
// as the base
|
||||||
switch(op->code()) {
|
switch(op->code()) {
|
||||||
case CPUI_RETURN:
|
|
||||||
case CPUI_CALL:
|
case CPUI_CALL:
|
||||||
case CPUI_CALLIND:
|
case CPUI_CALLIND:
|
||||||
// A constant parameter or return value could be a pointer
|
{
|
||||||
if (!glb->infer_pointers)
|
|
||||||
return (SymbolEntry *)0;
|
|
||||||
if (slot==0)
|
if (slot==0)
|
||||||
return (SymbolEntry *)0;
|
return (SymbolEntry *)0;
|
||||||
|
// A constant parameter could be a pointer
|
||||||
|
FuncCallSpecs *fc = data.getCallSpecs(op);
|
||||||
|
if (fc != (FuncCallSpecs *)0 && fc->isInputLocked() && fc->numParams() > slot-1) {
|
||||||
|
type_metatype meta = fc->getParam(slot-1)->getType()->getMetatype();
|
||||||
|
if (meta != TYPE_PTR && meta != TYPE_UNKNOWN) {
|
||||||
|
return (SymbolEntry *)0; // Definitely not passing a pointer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!glb->infer_pointers)
|
||||||
|
return (SymbolEntry *)0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CPUI_COPY:
|
||||||
|
if (!checkCopy(op, data))
|
||||||
|
return (SymbolEntry *)0;
|
||||||
break;
|
break;
|
||||||
case CPUI_PIECE:
|
case CPUI_PIECE:
|
||||||
// Pointers get concatenated in structures
|
// Pointers get concatenated in structures
|
||||||
case CPUI_COPY:
|
|
||||||
case CPUI_INT_EQUAL:
|
case CPUI_INT_EQUAL:
|
||||||
case CPUI_INT_NOTEQUAL:
|
case CPUI_INT_NOTEQUAL:
|
||||||
case CPUI_INT_LESS:
|
case CPUI_INT_LESS:
|
||||||
case CPUI_INT_LESSEQUAL:
|
case CPUI_INT_LESSEQUAL:
|
||||||
// A comparison with a constant could be a pointer
|
// A comparison with a constant could be a pointer
|
||||||
|
if (!glb->infer_pointers)
|
||||||
|
return (SymbolEntry *)0;
|
||||||
break;
|
break;
|
||||||
case CPUI_INT_ADD:
|
case CPUI_INT_ADD:
|
||||||
outvn = op->getOut();
|
outvn = op->getOut();
|
||||||
|
|
|
@ -189,6 +189,7 @@ class ActionConstantPtr : public Action {
|
||||||
int4 localcount; ///< Number of passes made for this function
|
int4 localcount; ///< Number of passes made for this function
|
||||||
static AddrSpace *searchForSpaceAttribute(Varnode *vn,PcodeOp *op);
|
static AddrSpace *searchForSpaceAttribute(Varnode *vn,PcodeOp *op);
|
||||||
static AddrSpace *selectInferSpace(Varnode *vn,PcodeOp *op,const vector<AddrSpace *> &spaceList);
|
static AddrSpace *selectInferSpace(Varnode *vn,PcodeOp *op,const vector<AddrSpace *> &spaceList);
|
||||||
|
static bool checkCopy(PcodeOp *op,Funcdata &data);
|
||||||
static SymbolEntry *isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,int4 slot,
|
static SymbolEntry *isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,int4 slot,
|
||||||
Address &rampoint,uintb &fullEncoding,Funcdata &data);
|
Address &rampoint,uintb &fullEncoding,Funcdata &data);
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -75,6 +75,8 @@ public abstract class RenameTask {
|
||||||
dialog.setStatusText("Cannot have empty name");
|
dialog.setStatusText("Cannot have empty name");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = name.trim();
|
||||||
if (name.equals(oldName)) { // No change to name
|
if (name.equals(oldName)) { // No change to name
|
||||||
newName = name;
|
newName = name;
|
||||||
return true; // but valid (ends up being equivalent to cancel
|
return true; // but valid (ends up being equivalent to cancel
|
||||||
|
|
|
@ -303,6 +303,17 @@ public class ReferenceDBManager implements ReferenceManager, ManagerDB, ErrorHan
|
||||||
* @return combined reference type, or the newType if unable to combine
|
* @return combined reference type, or the newType if unable to combine
|
||||||
*/
|
*/
|
||||||
private RefType combineReferenceType(RefType newType, RefType oldType) {
|
private RefType combineReferenceType(RefType newType, RefType oldType) {
|
||||||
|
// check if types are the same, if same no use doing work replacing reference
|
||||||
|
if (newType == oldType) {
|
||||||
|
return oldType;
|
||||||
|
}
|
||||||
|
// any flow reference should be used over the existing ref to the same location
|
||||||
|
if (newType.isFlow()) {
|
||||||
|
return newType; // allow any new flow ref to replace old type
|
||||||
|
}
|
||||||
|
if (oldType.isFlow()) {
|
||||||
|
return oldType; // always keep flow over new data ref
|
||||||
|
}
|
||||||
if (newType == RefType.DATA) {
|
if (newType == RefType.DATA) {
|
||||||
if (oldType.isData()) {
|
if (oldType.isData()) {
|
||||||
return oldType;
|
return oldType;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
##VERSION: 2.0
|
##VERSION: 2.0
|
||||||
Module.manifest||GHIDRA||||END|
|
Module.manifest||GHIDRA||||END|
|
||||||
data/languages/ARM-32-golang.cspec||GHIDRA||||END|
|
|
||||||
data/languages/ARM-32-golang.register.info||GHIDRA||||END|
|
|
||||||
data/languages/ARM.cspec||GHIDRA||||END|
|
data/languages/ARM.cspec||GHIDRA||||END|
|
||||||
data/languages/ARM.dwarf||GHIDRA||||END|
|
data/languages/ARM.dwarf||GHIDRA||||END|
|
||||||
data/languages/ARM.gdis||GHIDRA||||END|
|
data/languages/ARM.gdis||GHIDRA||||END|
|
||||||
|
|
|
@ -495,14 +495,14 @@ vcvt_56_128_dt: ".u32.f32"
|
||||||
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2327=0b00111 & c2021=0b11 & c1819=0b10 & c1617=0b11 & c0911=0b011 & c0404=0 & c0606=0)
|
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2327=0b00111 & c2021=0b11 & c1819=0b10 & c1617=0b11 & c0911=0b011 & c0404=0 & c0606=0)
|
||||||
| (TMode=1 & thv_c2831=0b1111 & thv_c2327=0b11111 & thv_c2021=0b11 & thv_c1819=0b10 & thv_c1617=0b11 & thv_c0911=0b011 & thv_c0404=0 & thv_c0606=0))
|
| (TMode=1 & thv_c2831=0b1111 & thv_c2327=0b11111 & thv_c2021=0b11 & thv_c1819=0b10 & thv_c1617=0b11 & thv_c0911=0b011 & thv_c0404=0 & thv_c0606=0))
|
||||||
& vcvt_56_64_dt & Dd & Dm
|
& vcvt_56_64_dt & Dd & Dm
|
||||||
unimpl
|
{ }
|
||||||
|
|
||||||
# F6.1.60 p8002 A1 Q == 1 (c0606)
|
# F6.1.60 p8002 A1 Q == 1 (c0606)
|
||||||
:vcvt^vcvt_56_128_dt Qd,Qm
|
:vcvt^vcvt_56_128_dt Qd,Qm
|
||||||
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2327=0b00111 & c2021=0b11 & c1819=0b10 & c1617=0b11 & c0911=0b011 & c0404=0 & c0606=1)
|
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2327=0b00111 & c2021=0b11 & c1819=0b10 & c1617=0b11 & c0911=0b011 & c0404=0 & c0606=1)
|
||||||
| (TMode=1 & thv_c2831=0b1111 & thv_c2327=0b11111 & thv_c2021=0b11 & thv_c1819=0b10 & thv_c1617=0b11 & thv_c0911=0b011 & thv_c0404=0 & thv_c0606=1))
|
| (TMode=1 & thv_c2831=0b1111 & thv_c2327=0b11111 & thv_c2021=0b11 & thv_c1819=0b10 & thv_c1617=0b11 & thv_c0911=0b011 & thv_c0404=0 & thv_c0606=1))
|
||||||
& vcvt_56_128_dt & Qd & Qm
|
& vcvt_56_128_dt & Qd & Qm
|
||||||
unimpl
|
{ }
|
||||||
|
|
||||||
# F6.1.61 p8005 A1 opc2==100 && size==10 (c1618, c0809)
|
# F6.1.61 p8005 A1 opc2==100 && size==10 (c1618, c0809)
|
||||||
:vcvt^COND^".u32.f32" Sd,Sm
|
:vcvt^COND^".u32.f32" Sd,Sm
|
||||||
|
@ -516,7 +516,7 @@ vcvt_56_128_dt: ".u32.f32"
|
||||||
is ((TMode=0 & ARMcond=1 & c2327=0b11101 & c1921=0b111 & c1011=0b10 & c0607=0b11 & c0404=0 & c1618=0b101 & c0809=0b10)
|
is ((TMode=0 & ARMcond=1 & c2327=0b11101 & c1921=0b111 & c1011=0b10 & c0607=0b11 & c0404=0 & c1618=0b101 & c0809=0b10)
|
||||||
| (TMode=1 & thv_c2831=0b1110 & thv_c2327=0b11101 & thv_c1921=0b111 & thv_c1011=0b10 & thv_c0607=0b11 & thv_c0404=0 & thv_c1618=0b101 & thv_c0809=0b10))
|
| (TMode=1 & thv_c2831=0b1110 & thv_c2327=0b11101 & thv_c1921=0b111 & thv_c1011=0b10 & thv_c0607=0b11 & thv_c0404=0 & thv_c1618=0b101 & thv_c0809=0b10))
|
||||||
& COND & Sd & Sm
|
& COND & Sd & Sm
|
||||||
{ build COND; Sd = zext(Sm f> 0) * (trunc(Sm)); }
|
{ build COND; Sd = trunc(Sm); }
|
||||||
|
|
||||||
# F6.1.61 p8005 A1 opc2==100 && size==11 (c1618, c0809)
|
# F6.1.61 p8005 A1 opc2==100 && size==11 (c1618, c0809)
|
||||||
:vcvt^COND^".u32.f64" Sd,Dm
|
:vcvt^COND^".u32.f64" Sd,Dm
|
||||||
|
@ -530,7 +530,7 @@ vcvt_56_128_dt: ".u32.f32"
|
||||||
is ((TMode=0 & ARMcond=1 & c2327=0b11101 & c1921=0b111 & c1011=0b10 & c0607=0b11 & c0404=0 & c1618=0b101 & c0809=0b11)
|
is ((TMode=0 & ARMcond=1 & c2327=0b11101 & c1921=0b111 & c1011=0b10 & c0607=0b11 & c0404=0 & c1618=0b101 & c0809=0b11)
|
||||||
| (TMode=1 & thv_c2831=0b1110 & thv_c2327=0b11101 & thv_c1921=0b111 & thv_c1011=0b10 & thv_c0607=0b11 & thv_c0404=0 & thv_c1618=0b101 & thv_c0809=0b11))
|
| (TMode=1 & thv_c2831=0b1110 & thv_c2327=0b11101 & thv_c1921=0b111 & thv_c1011=0b10 & thv_c0607=0b11 & thv_c0404=0 & thv_c1618=0b101 & thv_c0809=0b11))
|
||||||
& COND & Sd & Dm
|
& COND & Sd & Dm
|
||||||
{ build COND; local tmp:8 = zext(Dm f> 0:8) * (trunc(Dm)); Sd = tmp:4; }
|
{ build COND; local tmp:8 = trunc(Dm); Sd = tmp:4; }
|
||||||
|
|
||||||
# The rounding mode depends on c0707=0 => FPSCR else ZERO
|
# The rounding mode depends on c0707=0 => FPSCR else ZERO
|
||||||
|
|
||||||
|
@ -665,14 +665,14 @@ vcvt_59_64_dt: ".u16.f16"
|
||||||
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2527=0b001 & c2323=1 & c2121=1 & c1011=0b11 & c0707=0 & c0404=1 & c0606=0)
|
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2527=0b001 & c2323=1 & c2121=1 & c1011=0b11 & c0707=0 & c0404=1 & c0606=0)
|
||||||
| (TMode=1 & thv_c2931=0b111 & thv_c2327=0b11111 & thv_c2121=1 & thv_c1011=0b11 & thv_c0707=0 & thv_c0404=1 & thv_c0606=0))
|
| (TMode=1 & thv_c2931=0b111 & thv_c2327=0b11111 & thv_c2121=1 & thv_c1011=0b11 & thv_c0707=0 & thv_c0404=1 & thv_c0606=0))
|
||||||
& vcvt_59_32_dt & vcvt_59_fbits & Dd & Dm
|
& vcvt_59_32_dt & vcvt_59_fbits & Dd & Dm
|
||||||
unimpl
|
{ }
|
||||||
|
|
||||||
# F6.1.63 p8012 A1 Q = 1 (c0606)
|
# F6.1.63 p8012 A1 Q = 1 (c0606)
|
||||||
:vcvt^vcvt_59_64_dt Qd,Qm,vcvt_59_fbits
|
:vcvt^vcvt_59_64_dt Qd,Qm,vcvt_59_fbits
|
||||||
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2527=0b001 & c2323=1 & c2121=1 & c1011=0b11 & c0707=0 & c0404=1 & c0606=1)
|
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2527=0b001 & c2323=1 & c2121=1 & c1011=0b11 & c0707=0 & c0404=1 & c0606=1)
|
||||||
| (TMode=1 & thv_c2931=0b111 & thv_c2327=0b11111 & thv_c2121=1 & thv_c1011=0b11 & thv_c0707=0 & thv_c0404=1 & thv_c0606=1))
|
| (TMode=1 & thv_c2931=0b111 & thv_c2327=0b11111 & thv_c2121=1 & thv_c1011=0b11 & thv_c0707=0 & thv_c0404=1 & thv_c0606=1))
|
||||||
& vcvt_59_64_dt & vcvt_59_fbits & Qd & Qm
|
& vcvt_59_64_dt & vcvt_59_fbits & Qd & Qm
|
||||||
unimpl
|
{ }
|
||||||
|
|
||||||
vcvt_60_fbits_built: fbits is TMode=0 & c0707=0 & c0505 & c0003 [fbits = 16 - ( c0003 * 2 + c0505); ] { export * [const]:1 fbits; }
|
vcvt_60_fbits_built: fbits is TMode=0 & c0707=0 & c0505 & c0003 [fbits = 16 - ( c0003 * 2 + c0505); ] { export * [const]:1 fbits; }
|
||||||
vcvt_60_fbits_built: fbits is TMode=1 & thv_c0707=0 & thv_c0505 & thv_c0003 [fbits = 16 - (thv_c0003 * 2 + thv_c0505); ] { export * [const]:1 fbits; }
|
vcvt_60_fbits_built: fbits is TMode=1 & thv_c0707=0 & thv_c0505 & thv_c0003 [fbits = 16 - (thv_c0003 * 2 + thv_c0505); ] { export * [const]:1 fbits; }
|
||||||
|
@ -814,14 +814,14 @@ vcvt_amnp_simd_128_dt: ".u32" is TMode=1 & thv_c0707=1 & thv_c0809 & vcvt_amnp_s
|
||||||
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2327=0b00111 & c2021=0b11 & c1819=0b10 & c1617=0b11 & c1011=0b00 & c0404=0 & c0606=0)
|
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2327=0b00111 & c2021=0b11 & c1819=0b10 & c1617=0b11 & c1011=0b00 & c0404=0 & c0606=0)
|
||||||
| (TMode=1 & thv_c2831=0b1111 & thv_c2327=0b11111 & thv_c2021=0b11 & thv_c1819=0b10 & thv_c1617=0b11 & thv_c1011=0b00 & thv_c0404=0 & thv_c0606=0))
|
| (TMode=1 & thv_c2831=0b1111 & thv_c2327=0b11111 & thv_c2021=0b11 & thv_c1819=0b10 & thv_c1617=0b11 & thv_c1011=0b00 & thv_c0404=0 & thv_c0606=0))
|
||||||
& vcvt_amnp_simd_RM & vcvt_amnp_simd_64_dt & Dd & Dm
|
& vcvt_amnp_simd_RM & vcvt_amnp_simd_64_dt & Dd & Dm
|
||||||
unimpl
|
{ }
|
||||||
|
|
||||||
# F6.1.65,69,71,73 p8019,8028,8032,8036 A1 128-bit SIMD vector variant Q = 1(c0606)
|
# F6.1.65,69,71,73 p8019,8028,8032,8036 A1 128-bit SIMD vector variant Q = 1(c0606)
|
||||||
:vcvt^vcvt_amnp_simd_RM^vcvt_amnp_simd_128_dt^".f32" Qd,Qm
|
:vcvt^vcvt_amnp_simd_RM^vcvt_amnp_simd_128_dt^".f32" Qd,Qm
|
||||||
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2327=0b00111 & c2021=0b11 & c1819=0b10 & c1617=0b11 & c1011=0b00 & c0404=0 & c0606=1)
|
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2327=0b00111 & c2021=0b11 & c1819=0b10 & c1617=0b11 & c1011=0b00 & c0404=0 & c0606=1)
|
||||||
| (TMode=1 & thv_c2831=0b1111 & thv_c2327=0b11111 & thv_c2021=0b11 & thv_c1819=0b10 & thv_c1617=0b11 & thv_c1011=0b00 & thv_c0404=0 & thv_c0606=1))
|
| (TMode=1 & thv_c2831=0b1111 & thv_c2327=0b11111 & thv_c2021=0b11 & thv_c1819=0b10 & thv_c1617=0b11 & thv_c1011=0b00 & thv_c0404=0 & thv_c0606=1))
|
||||||
& vcvt_amnp_simd_RM & vcvt_amnp_simd_128_dt & Qd & Qm
|
& vcvt_amnp_simd_RM & vcvt_amnp_simd_128_dt & Qd & Qm
|
||||||
unimpl
|
{ }
|
||||||
|
|
||||||
vcvt_amnp_fp_RM: "a"
|
vcvt_amnp_fp_RM: "a"
|
||||||
is ((TMode=0 & c1617=0b00)
|
is ((TMode=0 & c1617=0b00)
|
||||||
|
@ -862,14 +862,14 @@ vcvt_amnp_fp_d_dt: ".s32" is TMode=1 & thv_c0707=1 & thv_c1617 & vcvt_amnp_fp_RM
|
||||||
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2327=0b11101 & c2021=0b11 & c1819=0b11 & c1011=0b10 & c0606=1 & c0404=0 & c0809=0b10)
|
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2327=0b11101 & c2021=0b11 & c1819=0b11 & c1011=0b10 & c0606=1 & c0404=0 & c0809=0b10)
|
||||||
| (TMode=1 & thv_c2831=0b1111 & thv_c2327=0b11101 & thv_c2021=0b11 & thv_c1819=0b11 & thv_c1011=0b10 & thv_c0606=1 & thv_c0404=0 & thv_c0809=0b10))
|
| (TMode=1 & thv_c2831=0b1111 & thv_c2327=0b11101 & thv_c2021=0b11 & thv_c1819=0b11 & thv_c1011=0b10 & thv_c0606=1 & thv_c0404=0 & thv_c0809=0b10))
|
||||||
& vcvt_amnp_fp_RM & vcvt_amnp_fp_s_dt & Sd & Sm
|
& vcvt_amnp_fp_RM & vcvt_amnp_fp_s_dt & Sd & Sm
|
||||||
unimpl
|
{ }
|
||||||
|
|
||||||
# F6.1.66,70,72,74 p8021,8030,8034,8038 Double-precision scalar variant size = 11 (c0809)
|
# F6.1.66,70,72,74 p8021,8030,8034,8038 Double-precision scalar variant size = 11 (c0809)
|
||||||
:vcvt^vcvt_amnp_fp_RM^vcvt_amnp_fp_d_dt^".f64" Sd,Dm
|
:vcvt^vcvt_amnp_fp_RM^vcvt_amnp_fp_d_dt^".f64" Sd,Dm
|
||||||
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2327=0b11101 & c2021=0b11 & c1819=0b11 & c1011=0b10 & c0606=1 & c0404=0 & c0809=0b11)
|
is ((TMode=0 & ARMcond=0 & c2831=0b1111 & c2327=0b11101 & c2021=0b11 & c1819=0b11 & c1011=0b10 & c0606=1 & c0404=0 & c0809=0b11)
|
||||||
| (TMode=1 & thv_c2831=0b1111 & thv_c2327=0b11101 & thv_c2021=0b11 & thv_c1819=0b11 & thv_c1011=0b10 & thv_c0606=1 & thv_c0404=0 & thv_c0809=0b11))
|
| (TMode=1 & thv_c2831=0b1111 & thv_c2327=0b11101 & thv_c2021=0b11 & thv_c1819=0b11 & thv_c1011=0b10 & thv_c0606=1 & thv_c0404=0 & thv_c0809=0b11))
|
||||||
& vcvt_amnp_fp_RM & vcvt_amnp_fp_d_dt & Sd & Dm
|
& vcvt_amnp_fp_RM & vcvt_amnp_fp_d_dt & Sd & Dm
|
||||||
unimpl
|
{ }
|
||||||
|
|
||||||
# vcvtb and vcvtt
|
# vcvtb and vcvtt
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue