mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 12:00:04 +02:00
GP-421 - Allow plate comments in structures; allow pre-comments at the
top of structures Closes #2091
This commit is contained in:
parent
d6e46d1270
commit
6ea07f858c
3 changed files with 62 additions and 32 deletions
|
@ -84,23 +84,30 @@ class CommentTableModel extends AddressBasedTableModel<CommentRowObject> {
|
||||||
listing.getCommentAddressIterator(getProgram().getMemory(), true);
|
listing.getCommentAddressIterator(getProgram().getMemory(), true);
|
||||||
while (commentIterator.hasNext()) {
|
while (commentIterator.hasNext()) {
|
||||||
Address commentAddr = commentIterator.next();
|
Address commentAddr = commentIterator.next();
|
||||||
CodeUnit cu = listing.getCodeUnitAt(commentAddr);
|
CodeUnit cu = listing.getCodeUnitContaining(commentAddr);
|
||||||
if (cu != null) {
|
if (!(cu instanceof Data)) {
|
||||||
if (cu.getComment(CodeUnit.PRE_COMMENT) != null) {
|
// avoid too many comments in the table by not showing offcut instruction comments
|
||||||
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.PRE_COMMENT));
|
cu = listing.getCodeUnitAt(commentAddr);
|
||||||
}
|
}
|
||||||
if (cu.getComment(CodeUnit.POST_COMMENT) != null) {
|
|
||||||
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.POST_COMMENT));
|
if (cu == null) {
|
||||||
}
|
continue;
|
||||||
if (cu.getComment(CodeUnit.EOL_COMMENT) != null) {
|
}
|
||||||
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.EOL_COMMENT));
|
|
||||||
}
|
if (cu.getComment(CodeUnit.PRE_COMMENT) != null) {
|
||||||
if (cu.getComment(CodeUnit.PLATE_COMMENT) != null) {
|
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.PRE_COMMENT));
|
||||||
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.PLATE_COMMENT));
|
}
|
||||||
}
|
if (cu.getComment(CodeUnit.POST_COMMENT) != null) {
|
||||||
if (cu.getComment(CodeUnit.REPEATABLE_COMMENT) != null) {
|
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.POST_COMMENT));
|
||||||
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.REPEATABLE_COMMENT));
|
}
|
||||||
}
|
if (cu.getComment(CodeUnit.EOL_COMMENT) != null) {
|
||||||
|
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.EOL_COMMENT));
|
||||||
|
}
|
||||||
|
if (cu.getComment(CodeUnit.PLATE_COMMENT) != null) {
|
||||||
|
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.PLATE_COMMENT));
|
||||||
|
}
|
||||||
|
if (cu.getComment(CodeUnit.REPEATABLE_COMMENT) != null) {
|
||||||
|
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.REPEATABLE_COMMENT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import ghidra.app.util.HighlightProvider;
|
||||||
import ghidra.app.util.viewer.format.FieldFormatModel;
|
import ghidra.app.util.viewer.format.FieldFormatModel;
|
||||||
import ghidra.app.util.viewer.listingpanel.ListingModel;
|
import ghidra.app.util.viewer.listingpanel.ListingModel;
|
||||||
import ghidra.app.util.viewer.options.OptionsGui;
|
import ghidra.app.util.viewer.options.OptionsGui;
|
||||||
|
import ghidra.app.util.viewer.proxy.DataProxy;
|
||||||
import ghidra.app.util.viewer.proxy.ProxyObj;
|
import ghidra.app.util.viewer.proxy.ProxyObj;
|
||||||
import ghidra.framework.options.Options;
|
import ghidra.framework.options.Options;
|
||||||
import ghidra.framework.options.ToolOptions;
|
import ghidra.framework.options.ToolOptions;
|
||||||
|
@ -126,10 +127,10 @@ public class PlateFieldFactory extends FieldFactory {
|
||||||
nLinesBeforeLabels = fieldOptions.getInt(LINES_BEFORE_LABELS_OPTION, 1);
|
nLinesBeforeLabels = fieldOptions.getInt(LINES_BEFORE_LABELS_OPTION, 1);
|
||||||
nLinesBeforePlates = fieldOptions.getInt(LINES_BEFORE_PLATES_OPTION, 0);
|
nLinesBeforePlates = fieldOptions.getInt(LINES_BEFORE_PLATES_OPTION, 0);
|
||||||
|
|
||||||
showExternalFunctionPointerPlates = fieldOptions.getBoolean(
|
showExternalFunctionPointerPlates = fieldOptions
|
||||||
ListingModel.DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME, true);
|
.getBoolean(ListingModel.DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME, true);
|
||||||
showNonExternalFunctionPointerPlates = fieldOptions.getBoolean(
|
showNonExternalFunctionPointerPlates = fieldOptions
|
||||||
ListingModel.DISPLAY_NONEXTERNAL_FUNCTION_POINTER_OPTION_NAME, false);
|
.getBoolean(ListingModel.DISPLAY_NONEXTERNAL_FUNCTION_POINTER_OPTION_NAME, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,11 +161,32 @@ public class PlateFieldFactory extends FieldFactory {
|
||||||
FieldElement[] fields = new FieldElement[elementList.size()];
|
FieldElement[] fields = new FieldElement[elementList.size()];
|
||||||
elementList.toArray(fields);
|
elementList.toArray(fields);
|
||||||
|
|
||||||
|
if (isNestedDataAtSameAddressAsParent(proxy)) {
|
||||||
|
// This is data at the same address as the parent, which happens with the first
|
||||||
|
// element in a structure. We do not want to the plate comment here, but only at the
|
||||||
|
// parent topmost address.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
PlateFieldTextField textField =
|
PlateFieldTextField textField =
|
||||||
new PlateFieldTextField(fields, this, proxy, startX, width, commentText, isClipped);
|
new PlateFieldTextField(fields, this, proxy, startX, width, commentText, isClipped);
|
||||||
return new PlateListingTextField(proxy, textField);
|
return new PlateListingTextField(proxy, textField);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isNestedDataAtSameAddressAsParent(ProxyObj<?> proxy) {
|
||||||
|
if (proxy instanceof DataProxy) {
|
||||||
|
DataProxy dp = (DataProxy) proxy;
|
||||||
|
Data data = dp.getObject();
|
||||||
|
int[] cpath = data.getComponentPath();
|
||||||
|
if (cpath.length > 0) {
|
||||||
|
if (cpath[cpath.length - 1] == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private String getCommentText(CodeUnit cu) {
|
private String getCommentText(CodeUnit cu) {
|
||||||
String[] comments = cu.getCommentAsArray(CodeUnit.PLATE_COMMENT);
|
String[] comments = cu.getCommentAsArray(CodeUnit.PLATE_COMMENT);
|
||||||
if (comments == null) {
|
if (comments == null) {
|
||||||
|
@ -199,8 +221,8 @@ public class PlateFieldFactory extends FieldFactory {
|
||||||
AttributedString prototype = new AttributedString(EMPTY_STRING, color, getMetrics());
|
AttributedString prototype = new AttributedString(EMPTY_STRING, color, getMetrics());
|
||||||
|
|
||||||
for (int i = 0; i < comments.length; i++) {
|
for (int i = 0; i < comments.length; i++) {
|
||||||
elementList.add(
|
elementList
|
||||||
CommentUtils.parseTextForAnnotations(comments[i], program, prototype, i));
|
.add(CommentUtils.parseTextForAnnotations(comments[i], program, prototype, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isWordWrap) {
|
if (isWordWrap) {
|
||||||
|
@ -499,7 +521,10 @@ public class PlateFieldFactory extends FieldFactory {
|
||||||
if (!CodeUnit.class.isAssignableFrom(proxyObjectClass)) {
|
if (!CodeUnit.class.isAssignableFrom(proxyObjectClass)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (category == FieldFormatModel.PLATE);
|
|
||||||
|
// some users like the look of plate comments and would like them in many places
|
||||||
|
return (category == FieldFormatModel.PLATE || category == FieldFormatModel.OPEN_DATA ||
|
||||||
|
category == FieldFormatModel.INSTRUCTION_OR_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -120,16 +120,14 @@ public class PreCommentFieldFactory extends FieldFactory {
|
||||||
|
|
||||||
private String[] getDefinedPreComments(CodeUnit cu) {
|
private String[] getDefinedPreComments(CodeUnit cu) {
|
||||||
|
|
||||||
// If this code unit is the outside of a data
|
// Do not show comments for nested components that share the same address as their parent
|
||||||
// container, then do not display any comments.
|
|
||||||
// If this was allowed, then the comment would appear
|
|
||||||
// on the outside data container and on the 1st
|
|
||||||
// internal member
|
|
||||||
//
|
|
||||||
if (cu instanceof Data) {
|
if (cu instanceof Data) {
|
||||||
Data data = (Data) cu;
|
Data data = (Data) cu;
|
||||||
if (data.getNumComponents() > 0) {
|
int[] cpath = data.getComponentPath();
|
||||||
return null;
|
if (cpath.length > 0) {
|
||||||
|
if (cpath[cpath.length - 1] == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue