mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 01:39:21 +02:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
1ca9e32a57
4 changed files with 91 additions and 61 deletions
|
@ -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.
|
||||
|
@ -57,13 +57,13 @@ class ProgramTextOptions {
|
|||
private final static int DEFAULT_OPERAND_WIDTH = 40;
|
||||
private final static int DEFAULT_EOL_WIDTH = 40;
|
||||
private final static int DEFAULT_REF_HEADER_WIDTH = 13;
|
||||
private final static int DEFAULT_REF_WIDTH = 40;
|
||||
private final static int DEFAULT_REF_WIDTH = 50; // about 4 refs per line
|
||||
private final static int DEFAULT_STACK_VAR_PRENAME_WIDTH = 10;
|
||||
private final static int DEFAULT_STACK_VAR_NAME_WIDTH = 15;
|
||||
private final static int DEFAULT_STACK_VAR_DATATYPE_WIDTH = 15;
|
||||
private final static int DEFAULT_STACK_VAR_OFFSET_WIDTH = 8;
|
||||
private final static int DEFAULT_STACK_VAR_COMMENT_WIDTH = 20;
|
||||
private final static int DEFAULT_STACK_VAR_XREF_WIDTH = 50;
|
||||
private final static int DEFAULT_STACK_VAR_XREF_WIDTH = 60; // about 5 refs per line
|
||||
private final static int DEFAULT_DATA_FIELD_NAME_WIDTH = 12;
|
||||
|
||||
private final static String DEFAULT_LABEL_SUFFIX = ":";
|
||||
|
|
|
@ -32,6 +32,7 @@ class ReferenceLineDispenser extends AbstractLineDispenser {
|
|||
private String header;
|
||||
private Memory memory;
|
||||
private ReferenceManager referenceManager;
|
||||
private boolean forwardRefs;
|
||||
|
||||
private List<String> lines = new ArrayList<>();
|
||||
|
||||
|
@ -50,11 +51,11 @@ class ReferenceLineDispenser extends AbstractLineDispenser {
|
|||
this.fillAmount =
|
||||
options.getAddrWidth() + options.getBytesWidth() + options.getLabelWidth();
|
||||
this.isHTML = options.isHTML();
|
||||
this.forwardRefs = forwardRefs;
|
||||
|
||||
List<Reference> refs = (forwardRefs ? getForwardRefs(cu) : getXRefList(cu));
|
||||
List<Reference> offcuts = (forwardRefs ? List.of() : getOffcutXRefList(cu));
|
||||
|
||||
processRefs(cu.getMinAddress(), forwardRefs, refs, offcuts);
|
||||
processRefs(cu.getMinAddress(), refs, offcuts);
|
||||
}
|
||||
|
||||
ReferenceLineDispenser(Variable var, Program program, ProgramTextOptions options) {
|
||||
|
@ -69,6 +70,7 @@ class ReferenceLineDispenser extends AbstractLineDispenser {
|
|||
options.getStackVarDataTypeWidth() + options.getStackVarOffsetWidth() +
|
||||
options.getStackVarCommentWidth();
|
||||
this.isHTML = options.isHTML();
|
||||
this.forwardRefs = false;
|
||||
|
||||
List<Reference> xrefs = new ArrayList<>();
|
||||
List<Reference> offcuts = new ArrayList<>();
|
||||
|
@ -80,7 +82,7 @@ class ReferenceLineDispenser extends AbstractLineDispenser {
|
|||
xrefs.sort(comparator);
|
||||
offcuts.sort(comparator);
|
||||
|
||||
processRefs(var.getFunction().getEntryPoint(), false, xrefs, offcuts);
|
||||
processRefs(var.getFunction().getEntryPoint(), xrefs, offcuts);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -133,8 +135,9 @@ class ReferenceLineDispenser extends AbstractLineDispenser {
|
|||
return refs;
|
||||
}
|
||||
|
||||
private void processRefs(Address addr, boolean isForward, List<Reference> refs,
|
||||
private void processRefs(Address addr, List<Reference> refs,
|
||||
List<Reference> offcuts) {
|
||||
|
||||
if (width < 1) {
|
||||
return;
|
||||
}
|
||||
|
@ -142,7 +145,7 @@ class ReferenceLineDispenser extends AbstractLineDispenser {
|
|||
return;
|
||||
}
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
List<Reference> all = new ArrayList<>();
|
||||
all.addAll(refs);
|
||||
all.addAll(offcuts);
|
||||
|
@ -160,60 +163,41 @@ class ReferenceLineDispenser extends AbstractLineDispenser {
|
|||
buf.append(clip(text, headerWidth));
|
||||
}
|
||||
}
|
||||
else {
|
||||
buf.append(getFill(headerWidth));
|
||||
buf.append(prefix);
|
||||
}
|
||||
|
||||
int refsPerLine = width / (all.get(0).toString().length() + XREFS_DELIM.length());
|
||||
int refsInCurrLine = 0;
|
||||
|
||||
int currentXrefWidth = 0;
|
||||
for (int i = 0; i < all.size(); ++i) {
|
||||
//if we are not displaying the xref header,
|
||||
//then we need to append the comment prefix
|
||||
if (i == 0 && !displayRefHeader) {
|
||||
buf.append(getFill(headerWidth));
|
||||
buf.append(prefix);
|
||||
}
|
||||
//if we have started a new line, then
|
||||
//we need to append the comment prefix
|
||||
if (refsInCurrLine == 0 && i != 0) {
|
||||
buf.append(getFill(headerWidth));
|
||||
if (!displayRefHeader) {
|
||||
buf.append(prefix);
|
||||
}
|
||||
}
|
||||
//if we already appended a ref to the line
|
||||
//and we are about to append one more,
|
||||
//then we need the delim
|
||||
if (refsInCurrLine > 0) {
|
||||
buf.append(XREFS_DELIM);
|
||||
}
|
||||
|
||||
//does memory contain this address? if so, then hyperlink it
|
||||
// does memory contain this address? if so, then hyperlink it
|
||||
Reference ref = all.get(i);
|
||||
Address address = isForward ? ref.getToAddress() : ref.getFromAddress();
|
||||
boolean isInMem = memory.contains(address);
|
||||
if (isHTML && isInMem) {
|
||||
buf.append("<A HREF=\"#" + getUniqueAddressString(address) + "\">");
|
||||
}
|
||||
buf.append(address);
|
||||
XrefItem xrefItem = new XrefItem(ref);
|
||||
|
||||
String refType = getRefTypeDisplayString(ref);
|
||||
buf.append(refType);
|
||||
|
||||
if (isHTML && isInMem) {
|
||||
buf.append("</A>");
|
||||
}
|
||||
|
||||
refsInCurrLine++;
|
||||
|
||||
if (refsInCurrLine == refsPerLine) {
|
||||
lines.add((displayRefHeader ? prefix : "") + buf.toString());
|
||||
int nextWidth = currentXrefWidth + xrefItem.getDisplayableWidth();
|
||||
if (nextWidth > width) {
|
||||
// line is too long for the current xref, break
|
||||
lines.add(prefix + buf.toString());
|
||||
buf.delete(0, buf.length());
|
||||
refsInCurrLine = 0;
|
||||
|
||||
// since we already have the next xref, add the next line's prefix
|
||||
buf.append(getFill(headerWidth));
|
||||
|
||||
currentXrefWidth = 0;
|
||||
}
|
||||
|
||||
currentXrefWidth += xrefItem.getDisplayableWidth();
|
||||
buf.append(xrefItem.getRawText());
|
||||
|
||||
if (i < all.size() - 1) {
|
||||
buf.append(XREFS_DELIM);
|
||||
}
|
||||
}
|
||||
|
||||
if (refsInCurrLine > 0) {
|
||||
lines.add((displayRefHeader ? prefix : "") + buf.toString());
|
||||
buf.delete(0, buf.length());
|
||||
// add the last xref line
|
||||
if (buf.length() != 0) {
|
||||
lines.add(prefix + buf.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,4 +279,29 @@ class ReferenceLineDispenser extends AbstractLineDispenser {
|
|||
});
|
||||
return offcutList;
|
||||
}
|
||||
|
||||
private class XrefItem {
|
||||
private Address address;
|
||||
private String displayableString;
|
||||
|
||||
XrefItem(Reference ref) {
|
||||
address = forwardRefs ? ref.getToAddress() : ref.getFromAddress();
|
||||
String refType = getRefTypeDisplayString(ref);
|
||||
this.displayableString = address.toString() + refType;
|
||||
}
|
||||
|
||||
int getDisplayableWidth() {
|
||||
return displayableString.length();
|
||||
}
|
||||
|
||||
String getRawText() {
|
||||
boolean isInMem = memory.contains(address);
|
||||
if (isHTML && isInMem) {
|
||||
String href = getUniqueAddressString(address);
|
||||
return "<A HREF=\"#%s\">%s</A>".formatted(href, displayableString);
|
||||
}
|
||||
|
||||
return displayableString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -24,10 +24,11 @@ import ghidra.util.Msg;
|
|||
|
||||
public class StringComparer {
|
||||
public static void compareLines(List<String> expectedList, File actualFile) throws Exception {
|
||||
|
||||
FilePrinter filePrinter = new FilePrinter(actualFile);
|
||||
|
||||
int index = 0;
|
||||
|
||||
boolean hasFailure = false;
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(actualFile))) {
|
||||
int excess = 0;
|
||||
while (true) {
|
||||
|
@ -51,17 +52,21 @@ public class StringComparer {
|
|||
hasFailure |= !match;
|
||||
|
||||
if (!match) {
|
||||
Msg.debug(StringComparer.class, "Expected line does not match actual line (" + index +
|
||||
"): \nExpected: " + expectedLine + "\nActual: " + actualLine);
|
||||
filePrinter.print();
|
||||
Msg.debug(StringComparer.class,
|
||||
"Expected line does not match actual line (" + index +
|
||||
"): \nExpected: " + expectedLine + "\nActual: " + actualLine);
|
||||
}
|
||||
}
|
||||
|
||||
if (excess > 0) {
|
||||
filePrinter.print();
|
||||
String message = "Actual file contains " + excess + " more lines than expected";
|
||||
Msg.debug(StringComparer.class, message);
|
||||
Assert.fail(message);
|
||||
}
|
||||
else if (!hasFailure && index < expectedList.size()) {
|
||||
filePrinter.print();
|
||||
int fewer = expectedList.size() - index;
|
||||
String message = "Actual file contains " + fewer +
|
||||
" fewer lines than expected";
|
||||
|
@ -74,4 +79,20 @@ public class StringComparer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class FilePrinter {
|
||||
private File f;
|
||||
private boolean printed;
|
||||
|
||||
FilePrinter(File f) {
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
void print() {
|
||||
if (!printed) {
|
||||
Msg.debug(this, "Test file: " + f);
|
||||
printed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ public class XrefViewerTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
01001046 ?? thunk_FUN_01001005 UNCONDITIONAL_CALL thunk
|
||||
*/
|
||||
|
||||
doubleClickXRef(baseFunctionAddress, "XREF[1]: ");
|
||||
doubleClickXRef(baseFunctionAddress, "XREF[2]: ");
|
||||
ComponentProvider comp = waitForComponentProvider(TableComponentProvider.class);
|
||||
TableComponentProvider<?> tableProvider = (TableComponentProvider<?>) comp;
|
||||
GhidraProgramTableModel<?> model = tableProvider.getModel();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue