mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-27 16:56:16 +08:00
GP-6691 - Data Type Finder - Updated search results to include the field name if one is available. Added a new table column to show just the field name.
This commit is contained in:
+11
-3
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -16,6 +16,7 @@
|
||||
package ghidra.app.plugin.core.navigation.locationreferences;
|
||||
|
||||
import ghidra.program.database.symbol.FunctionSymbol;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
@@ -67,7 +68,14 @@ public class FunctionDefinitionLocationDescriptor extends GenericDataTypeLocatio
|
||||
continue;
|
||||
}
|
||||
|
||||
accumulator.add(new LocationReference(symbol.getAddress()));
|
||||
ProgramLocation location = symbol.getProgramLocation();
|
||||
Address address = symbol.getAddress();
|
||||
if (location != null) {
|
||||
accumulator.add(new LocationReference(address, null, location));
|
||||
}
|
||||
else {
|
||||
accumulator.add(new LocationReference(address));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-4
@@ -38,6 +38,11 @@ public class LocationReference implements Comparable<LocationReference> {
|
||||
private final SearchLocationContext context;
|
||||
private final ProgramLocation location;
|
||||
|
||||
/**
|
||||
* Optional field name.
|
||||
*/
|
||||
private String fieldName;
|
||||
|
||||
/**
|
||||
* Optional reference object. Some clients do not have actual references.
|
||||
*/
|
||||
@@ -67,20 +72,25 @@ public class LocationReference implements Comparable<LocationReference> {
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
LocationReference(Address locationOfUseAddress, String refType, boolean isOffcutReference) {
|
||||
this(locationOfUseAddress, null, refType, EMPTY_CONTEXT, isOffcutReference);
|
||||
LocationReference(Reference reference, boolean isOffcutReference, String fieldName) {
|
||||
this(reference.getFromAddress(), null, getRefType(reference), EMPTY_CONTEXT,
|
||||
isOffcutReference);
|
||||
this.reference = reference;
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
LocationReference(Address locationOfUseAddress) {
|
||||
this(locationOfUseAddress, null, null, EMPTY_CONTEXT, false);
|
||||
}
|
||||
|
||||
LocationReference(Address locationOfUseAddress, String context) {
|
||||
LocationReference(Address locationOfUseAddress, SearchLocationContext context) {
|
||||
this(locationOfUseAddress, null, null, SearchLocationContext.get(context), false);
|
||||
}
|
||||
|
||||
LocationReference(Address locationOfUseAddress, SearchLocationContext context) {
|
||||
LocationReference(Address locationOfUseAddress, SearchLocationContext context,
|
||||
String fieldName) {
|
||||
this(locationOfUseAddress, null, null, SearchLocationContext.get(context), false);
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
LocationReference(Address locationOfUseAddress, String context, ProgramLocation location) {
|
||||
@@ -150,6 +160,14 @@ public class LocationReference implements Comparable<LocationReference> {
|
||||
return reference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field name for this location reference or null if there is no field name.
|
||||
* @return the field name; may be null
|
||||
*/
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class has a {@link Reference} and that reference is not dynamic (i.e.,
|
||||
* the reference exists in the database).
|
||||
|
||||
+25
-3
@@ -23,6 +23,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import docking.widgets.search.SearchLocationContext;
|
||||
import docking.widgets.search.SearchLocationContextRenderer;
|
||||
import docking.widgets.table.GTableCellRenderingData;
|
||||
import docking.widgets.table.TableColumnDescriptor;
|
||||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.program.model.address.Address;
|
||||
@@ -57,8 +58,14 @@ class LocationReferencesTableModel extends AddressBasedTableModel<LocationRefere
|
||||
super("References", locationReferencesProvider.getTool(),
|
||||
locationReferencesProvider.getProgram(), null, true);
|
||||
this.provider = locationReferencesProvider;
|
||||
}
|
||||
|
||||
addTableColumn(new ContextTableColumn());
|
||||
@Override
|
||||
protected TableColumnDescriptor<LocationReference> createTableColumnDescriptor() {
|
||||
TableColumnDescriptor<LocationReference> descriptor = super.createTableColumnDescriptor();
|
||||
descriptor.addVisibleColumn(new ContextColumn());
|
||||
descriptor.addHiddenColumn(new FieldNameColumn());
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,7 +135,7 @@ class LocationReferencesTableModel extends AddressBasedTableModel<LocationRefere
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
|
||||
private class ContextTableColumn
|
||||
private class ContextColumn
|
||||
extends AbstractProgramBasedDynamicTableColumn<LocationReference, LocationReference> {
|
||||
|
||||
private static final String OFFCUT_STRING = "<< OFFCUT >>";
|
||||
@@ -262,7 +269,7 @@ class LocationReferencesTableModel extends AddressBasedTableModel<LocationRefere
|
||||
}
|
||||
|
||||
SearchLocationContext context = rowObject.getContext();
|
||||
return contextRenderer.renderHtmlContext(data, context);
|
||||
return contextRenderer.renderHtmlContext(data, context, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -279,4 +286,19 @@ class LocationReferencesTableModel extends AddressBasedTableModel<LocationRefere
|
||||
|
||||
}
|
||||
|
||||
private class FieldNameColumn
|
||||
extends AbstractProgramBasedDynamicTableColumn<LocationReference, String> {
|
||||
|
||||
@Override
|
||||
public String getColumnName() {
|
||||
return "Field Name";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(LocationReference rowObject, Settings settings,
|
||||
Program data, ServiceProvider sp) throws IllegalArgumentException {
|
||||
return rowObject.getFieldName();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+26
-11
@@ -330,7 +330,9 @@ public final class ReferenceUtils {
|
||||
Consumer<DataTypeReference> callback = ref -> {
|
||||
|
||||
SearchLocationContext context = ref.getContext();
|
||||
LocationReference locationReference = new LocationReference(ref.getAddress(), context);
|
||||
String fieldName = ref.getFieldName();
|
||||
LocationReference locationReference =
|
||||
new LocationReference(ref.getAddress(), context, fieldName);
|
||||
accumulator.add(locationReference);
|
||||
};
|
||||
|
||||
@@ -1039,9 +1041,11 @@ public final class ReferenceUtils {
|
||||
private static LocationReference createReferenceFromDefinedData(Data data,
|
||||
FieldMatcher fieldMatcher) {
|
||||
Address dataAddress = data.getMinAddress();
|
||||
String pathName = data.getPathName();
|
||||
if (fieldMatcher.isIgnored()) {
|
||||
// no field to match; include the hit
|
||||
return new LocationReference(dataAddress, data.getPathName());
|
||||
SearchLocationContext context = SearchLocationContext.get(pathName);
|
||||
return new LocationReference(dataAddress, context);
|
||||
}
|
||||
|
||||
DataType dt = data.getDataType();
|
||||
@@ -1052,8 +1056,11 @@ public final class ReferenceUtils {
|
||||
}
|
||||
|
||||
DataType baseDt = getBaseDataType(data.getDataType());
|
||||
String fieldName = fieldMatcher.getFieldName();
|
||||
if (matchesEnumField(data, baseDt, fieldMatcher)) {
|
||||
return new LocationReference(dataAddress, fieldMatcher.getDisplayText());
|
||||
String text = fieldMatcher.getDisplayText();
|
||||
SearchLocationContext context = SearchLocationContext.get(text);
|
||||
return new LocationReference(dataAddress, context, fieldName);
|
||||
}
|
||||
|
||||
DataTypeComponent component = getDataTypeComponent(baseDt, fieldMatcher);
|
||||
@@ -1064,13 +1071,14 @@ public final class ReferenceUtils {
|
||||
Address componentAddress;
|
||||
try {
|
||||
componentAddress = dataAddress.addNoWrap(component.getOffset());
|
||||
return new LocationReference(componentAddress,
|
||||
data.getPathName() + "." + fieldMatcher.getFieldName());
|
||||
String text = pathName + "." + fieldName;
|
||||
SearchLocationContext context = SearchLocationContext.get(text);
|
||||
return new LocationReference(componentAddress, context, fieldName);
|
||||
}
|
||||
catch (AddressOverflowException e) {
|
||||
// shouldn't happen
|
||||
Msg.error(ReferenceUtils.class, "Unable to create address for sub-component of " +
|
||||
data.getPathName() + " at " + dataAddress, e);
|
||||
pathName + " at " + dataAddress, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1165,7 +1173,7 @@ public final class ReferenceUtils {
|
||||
Consumer<LocationReference> consumer =
|
||||
locationReference -> accumulator.add(locationReference);
|
||||
Program program = data.getProgram();
|
||||
accumulateDirectReferences(consumer, program, dataAddress);
|
||||
accumulateDirectReferences(consumer, program, fieldMatcher, dataAddress);
|
||||
|
||||
Consumer<Reference> referenceConsumer = reference -> {
|
||||
Address toAddress = reference.getToAddress();
|
||||
@@ -1177,7 +1185,8 @@ public final class ReferenceUtils {
|
||||
|
||||
// have a field match; only add the reference if it is directly to the field
|
||||
if (toAddress.equals(dataAddress)) {
|
||||
accumulator.add(new LocationReference(reference, false));
|
||||
String fieldName = fieldMatcher.getFieldName();
|
||||
accumulator.add(new LocationReference(reference, false, fieldName));
|
||||
}
|
||||
};
|
||||
accumulateOffcutReferences(referenceConsumer, data, monitor);
|
||||
@@ -1264,8 +1273,8 @@ public final class ReferenceUtils {
|
||||
ReferenceManager referenceManager = program.getReferenceManager();
|
||||
Reference[] variableRefsTo = referenceManager.getReferencesTo(variable);
|
||||
for (Reference ref : variableRefsTo) {
|
||||
accumulator
|
||||
.add(new LocationReference(ref, !ref.getToAddress().equals(variableAddress)));
|
||||
Address toAddress = ref.getToAddress();
|
||||
accumulator.add(new LocationReference(ref, !toAddress.equals(variableAddress)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1348,12 +1357,18 @@ public final class ReferenceUtils {
|
||||
|
||||
private static void accumulateDirectReferences(Consumer<LocationReference> consumer,
|
||||
Program program, Address address) {
|
||||
accumulateDirectReferences(consumer, program, null, address);
|
||||
}
|
||||
|
||||
private static void accumulateDirectReferences(Consumer<LocationReference> consumer,
|
||||
Program program, FieldMatcher fieldMatcher, Address address) {
|
||||
|
||||
String fieldName = fieldMatcher != null ? fieldMatcher.getFieldName() : null;
|
||||
boolean isOffcut = isOffcut(program, address);
|
||||
ReferenceIterator iter = program.getReferenceManager().getReferencesTo(address);
|
||||
while (iter.hasNext()) {
|
||||
Reference ref = iter.next();
|
||||
consumer.accept(new LocationReference(ref, isOffcut));
|
||||
consumer.accept(new LocationReference(ref, isOffcut, fieldName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -72,7 +72,7 @@ class XRefLocationDescriptor extends LocationDescriptor {
|
||||
}
|
||||
|
||||
protected Address getXRefAddress(ProgramLocation location) {
|
||||
return ((XRefFieldLocation) location).getRefAddress();
|
||||
return location.getRefAddress();
|
||||
}
|
||||
|
||||
protected String getLabelForLocation(ProgramLocation location) {
|
||||
|
||||
@@ -58,6 +58,10 @@ public class DataTypeReference {
|
||||
return context;
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String fieldNameText = fieldName == null ? "" : "\tfieldName: " + fieldName + "\n";
|
||||
|
||||
Reference in New Issue
Block a user