mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-12-04 18:13:11 +00:00
Merge remote-tracking branch 'origin/GP-5155-dragonmacher-diff-missing-parameters--SQUASHED'
This commit is contained in:
commit
b17f459538
@ -184,7 +184,7 @@ public class SymbolSearcher {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Symbol s = program.getSymbolTable().getPrimarySymbol(address);
|
Symbol s = program.getSymbolTable().getPrimarySymbol(address);
|
||||||
if (s.isDynamic()) { // non-dynamic symbols have already been searched (ex, FUN_12345678)
|
if (s != null && s.isDynamic()) { // non-dynamic symbols have already been searched (ex, FUN_12345678)
|
||||||
addSymbolIfMatches(s, locations);
|
addSymbolIfMatches(s, locations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -18,9 +18,9 @@ package ghidra.app.util.viewer.multilisting;
|
|||||||
import docking.widgets.fieldpanel.Layout;
|
import docking.widgets.fieldpanel.Layout;
|
||||||
import docking.widgets.fieldpanel.field.Field;
|
import docking.widgets.fieldpanel.field.Field;
|
||||||
import docking.widgets.fieldpanel.support.MultiRowLayout;
|
import docking.widgets.fieldpanel.support.MultiRowLayout;
|
||||||
|
import docking.widgets.fieldpanel.support.MultiRowLayout.RowHeights;
|
||||||
import docking.widgets.fieldpanel.support.RowLayout;
|
import docking.widgets.fieldpanel.support.RowLayout;
|
||||||
import ghidra.app.util.viewer.field.DummyFieldFactory;
|
import ghidra.app.util.viewer.field.DummyFieldFactory;
|
||||||
import ghidra.app.util.viewer.format.FormatManager;
|
|
||||||
import ghidra.app.util.viewer.proxy.EmptyProxy;
|
import ghidra.app.util.viewer.proxy.EmptyProxy;
|
||||||
|
|
||||||
class MultiLayout {
|
class MultiLayout {
|
||||||
@ -29,22 +29,30 @@ class MultiLayout {
|
|||||||
public MultiLayout() {
|
public MultiLayout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MultiLayout(Layout[] layouts, FormatManager formatMgr, DummyFieldFactory factory) {
|
public MultiLayout(Layout[] layouts, DummyFieldFactory factory) {
|
||||||
this.layouts = layouts;
|
this.layouts = layouts;
|
||||||
int[] rowHeights = new int[formatMgr.getMaxNumRows()];
|
|
||||||
|
RowHeights[] allHeights = new RowHeights[layouts.length];
|
||||||
int id = getDefaultID(layouts);
|
int id = getDefaultID(layouts);
|
||||||
for (int i = 0; i < layouts.length; i++) {
|
for (int i = 0; i < layouts.length; i++) {
|
||||||
MultiRowLayout layout = (MultiRowLayout) layouts[i];
|
MultiRowLayout layout = (MultiRowLayout) layouts[i];
|
||||||
if (layout == null) {
|
if (layout == null) {
|
||||||
layout = new MultiRowLayout(
|
Field[] fields = new Field[] { factory.getField(EmptyProxy.EMPTY_PROXY, 0) };
|
||||||
new RowLayout(new Field[] { factory.getField(EmptyProxy.EMPTY_PROXY, 0) }, id),
|
layout = new MultiRowLayout(new RowLayout(fields, id), 1);
|
||||||
1);
|
|
||||||
layouts[i] = layout;
|
layouts[i] = layout;
|
||||||
}
|
}
|
||||||
layout.fillHeights(rowHeights);
|
|
||||||
|
allHeights[i] = layout.getRowHeights();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int n = allHeights.length;
|
||||||
|
RowHeights combinedRowHeights = new RowHeights();
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
combinedRowHeights.merge(allHeights[i]);
|
||||||
|
}
|
||||||
|
|
||||||
for (Layout layout : layouts) {
|
for (Layout layout : layouts) {
|
||||||
((MultiRowLayout) layout).align(rowHeights);
|
((MultiRowLayout) layout).align(combinedRowHeights);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,12 +70,7 @@ class MultiLayout {
|
|||||||
return layouts == null;
|
return layouts == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param modelID
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Layout getLayout(int modelID) {
|
public Layout getLayout(int modelID) {
|
||||||
return layouts[modelID];
|
return layouts[modelID];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,7 @@ public class MultiListingLayoutModel implements ListingModelListener, FormatMode
|
|||||||
/**
|
/**
|
||||||
* Returns the ListingLayoutModel for the i'th program.
|
* Returns the ListingLayoutModel for the i'th program.
|
||||||
* @param index the index of program for which to return a listing model
|
* @param index the index of program for which to return a listing model
|
||||||
|
* @return the the ListingLayoutModel for the i'th program.
|
||||||
*/
|
*/
|
||||||
public ListingModel getAlignedModel(int index) {
|
public ListingModel getAlignedModel(int index) {
|
||||||
return alignedModels[index];
|
return alignedModels[index];
|
||||||
@ -124,7 +125,7 @@ public class MultiListingLayoutModel implements ListingModelListener, FormatMode
|
|||||||
hasLayout |= layouts[i] != null;
|
hasLayout |= layouts[i] != null;
|
||||||
}
|
}
|
||||||
if (hasLayout) {
|
if (hasLayout) {
|
||||||
ml = new MultiLayout(layouts, formatMgr, emptyFactory);
|
ml = new MultiLayout(layouts, emptyFactory);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ml = new MultiLayout();
|
ml = new MultiLayout();
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -17,8 +17,8 @@ package docking.widgets.fieldpanel.support;
|
|||||||
|
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ import docking.widgets.fieldpanel.field.Field;
|
|||||||
import docking.widgets.fieldpanel.internal.*;
|
import docking.widgets.fieldpanel.internal.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles layouts with muliple rows.
|
* Handles layouts with multiple rows.
|
||||||
*/
|
*/
|
||||||
public class MultiRowLayout implements Layout {
|
public class MultiRowLayout implements Layout {
|
||||||
private RowLayout[] layouts;
|
private RowLayout[] layouts;
|
||||||
@ -42,6 +42,7 @@ public class MultiRowLayout implements Layout {
|
|||||||
/**
|
/**
|
||||||
* Constructs a new MultiRowLayout with a single layout row.
|
* Constructs a new MultiRowLayout with a single layout row.
|
||||||
* @param layout the single layout to add to this MultiRowLayout.
|
* @param layout the single layout to add to this MultiRowLayout.
|
||||||
|
* @param indexSize the index size.
|
||||||
*/
|
*/
|
||||||
public MultiRowLayout(RowLayout layout, int indexSize) {
|
public MultiRowLayout(RowLayout layout, int indexSize) {
|
||||||
this.indexSize = indexSize;
|
this.indexSize = indexSize;
|
||||||
@ -57,6 +58,7 @@ public class MultiRowLayout implements Layout {
|
|||||||
this.indexSize = indexSize;
|
this.indexSize = indexSize;
|
||||||
this.layouts = layouts;
|
this.layouts = layouts;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
|
|
||||||
for (RowLayout layout : layouts) {
|
for (RowLayout layout : layouts) {
|
||||||
numFields += layout.getNumFields();
|
numFields += layout.getNumFields();
|
||||||
height += layout.getHeight();
|
height += layout.getHeight();
|
||||||
@ -362,83 +364,12 @@ public class MultiRowLayout implements Layout {
|
|||||||
heightBelow += size;
|
heightBelow += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Fills in the given array with the heights of all the layouts in the MultiRowLayout
|
public String toString() {
|
||||||
* @param rowHeights the array to be filled in with heights. Each height is stored at
|
return Arrays.asList(layouts)
|
||||||
* its layoutRow id as the index into the array.
|
.stream()
|
||||||
*/
|
.map(RowLayout::toString)
|
||||||
public void fillHeights(int[] rowHeights) {
|
.collect(Collectors.joining("\n"));
|
||||||
int lastId = -1;
|
|
||||||
int height = 0;
|
|
||||||
for (RowLayout layout : layouts) {
|
|
||||||
int id = layout.getRowID();
|
|
||||||
if (id == lastId) {
|
|
||||||
height += layout.getHeight();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (lastId >= 0) {
|
|
||||||
rowHeights[lastId] = Math.max(rowHeights[lastId], height);
|
|
||||||
}
|
|
||||||
lastId = id;
|
|
||||||
height = layout.getHeight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lastId >= 0) {
|
|
||||||
rowHeights[lastId] = Math.max(rowHeights[lastId], height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class EmptyRowLayout extends RowLayout {
|
|
||||||
|
|
||||||
public EmptyRowLayout(int rowId, int height) {
|
|
||||||
super(getEmptyFields(height), rowId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Field[] getEmptyFields(int height) {
|
|
||||||
return new Field[] { new EmptyTextField(height, 0, 0, 0) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Aligns the heights in this MultiRowLayout to match those in the give row heights array.
|
|
||||||
* Extra is inserted to align the rows in this layout to match those specified in the given array.
|
|
||||||
* @param rowHeights the aray of row height to align to.
|
|
||||||
*/
|
|
||||||
public void align(int[] rowHeights) {
|
|
||||||
int row = 0;
|
|
||||||
List<RowLayout> updatedRows = new ArrayList<>();
|
|
||||||
for (RowLayout layout : layouts) {
|
|
||||||
int id = layout.getRowID();
|
|
||||||
for (; row <= id; row++) {
|
|
||||||
if (rowHeights[row] == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (row == id) {
|
|
||||||
layout.insertSpaceBelow(rowHeights[id] - layout.getHeight());
|
|
||||||
updatedRows.add(layout);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updatedRows.add(new EmptyRowLayout(row, rowHeights[row]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; row < rowHeights.length; row++) {
|
|
||||||
if (rowHeights[row] != 0) {
|
|
||||||
updatedRows.add(new EmptyRowLayout(row, rowHeights[row]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int height = 0;
|
|
||||||
layouts = new RowLayout[updatedRows.size()];
|
|
||||||
for (int i = 0; i < layouts.length; i++) {
|
|
||||||
layouts[i] = updatedRows.get(i);
|
|
||||||
height += layouts[i].getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
heightAbove = layouts[0].getHeightAbove();
|
|
||||||
heightBelow = height - heightAbove;
|
|
||||||
buildOffsets();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -470,4 +401,147 @@ public class MultiRowLayout implements Layout {
|
|||||||
return layouts[0].getRowID();
|
return layouts[0].getRowID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an object that contains all row heights for the row layouts in this class.
|
||||||
|
* @return an object that contains all row heights for the row layouts in this class.
|
||||||
|
*/
|
||||||
|
public RowHeights getRowHeights() {
|
||||||
|
RowHeights rowHeights = new RowHeights();
|
||||||
|
for (RowLayout layout : layouts) {
|
||||||
|
rowHeights.addHeight(layout);
|
||||||
|
}
|
||||||
|
return rowHeights;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aligns the heights in this MultiRowLayout to match those in the given row heights array.
|
||||||
|
* This is used by the diff provider to align two sets of rows.
|
||||||
|
*
|
||||||
|
* @param sharedRowHeights the row heights
|
||||||
|
*/
|
||||||
|
public void align(RowHeights sharedRowHeights) {
|
||||||
|
|
||||||
|
// Gather and map all layouts by their assigned row number. This map *may not* be a
|
||||||
|
// complete range of rows from 0 to rowHeights.length;
|
||||||
|
Map<Integer, List<RowLayout>> layoutsByRow = new HashMap<>();
|
||||||
|
for (RowLayout layout : layouts) {
|
||||||
|
int row = layout.getRowID();
|
||||||
|
List<RowLayout> list = layoutsByRow.computeIfAbsent(row, k -> new ArrayList<>());
|
||||||
|
list.add(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Walk the entire range of shared rows between each diff. If a row height is 0, then
|
||||||
|
// neither side of the diff contains a RowLayout object for that row.
|
||||||
|
List<RowLayout> updatedRows = alignRows(sharedRowHeights, layoutsByRow);
|
||||||
|
layouts = new RowLayout[updatedRows.size()];
|
||||||
|
int height = 0;
|
||||||
|
for (int i = 0; i < layouts.length; i++) {
|
||||||
|
layouts[i] = updatedRows.get(i);
|
||||||
|
height += layouts[i].getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
heightAbove = layouts[0].getHeightAbove();
|
||||||
|
heightBelow = height - heightAbove;
|
||||||
|
buildOffsets();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<RowLayout> alignRows(RowHeights sharedRowHeights,
|
||||||
|
Map<Integer, List<RowLayout>> layoutsByRow) {
|
||||||
|
|
||||||
|
List<RowLayout> updatedRows = new ArrayList<>();
|
||||||
|
int totalRows = sharedRowHeights.getRowCount(); // total rows shared between all views
|
||||||
|
for (int row = 0; row < totalRows; row++) {
|
||||||
|
int rowHeight = sharedRowHeights.getHeight(row);
|
||||||
|
if (rowHeight == 0) {
|
||||||
|
continue; // no rows on either side
|
||||||
|
}
|
||||||
|
|
||||||
|
List<RowLayout> rowLayouts = layoutsByRow.get(row);
|
||||||
|
if (rowLayouts == null) {
|
||||||
|
// No lines for this row. This side of the diff that has no rows fields for the
|
||||||
|
// given row. Add empty rows to act as spacers for this side of the diff.
|
||||||
|
updatedRows.add(new EmptyRowLayout(row, rowHeight));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point we have one or more lines to add for the current row. Add each line
|
||||||
|
// but the last line. The last line will consume all remaining height that has not yet
|
||||||
|
// been consumed.
|
||||||
|
int totalLines = rowLayouts.size();
|
||||||
|
int lastLine = totalLines - 1;
|
||||||
|
int allButLastLine = lastLine - 1;
|
||||||
|
int consumedHeight = 0; // track all height used by each row
|
||||||
|
for (int line = 0; line <= allButLastLine; line++) {
|
||||||
|
RowLayout layout = rowLayouts.get(line);
|
||||||
|
updatedRows.add(layout);
|
||||||
|
consumedHeight += layout.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the last line, adding any space to fill the remaining row height. Having
|
||||||
|
// remaining height means that the other side of the diff has more RowLayouts than this
|
||||||
|
// side of the diff.
|
||||||
|
RowLayout layout = rowLayouts.get(lastLine);
|
||||||
|
consumedHeight += layout.getHeight();
|
||||||
|
int leftOverHeight = rowHeight - consumedHeight;
|
||||||
|
layout.insertSpaceBelow(leftOverHeight);
|
||||||
|
updatedRows.add(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class EmptyRowLayout extends RowLayout {
|
||||||
|
|
||||||
|
public EmptyRowLayout(int rowId, int height) {
|
||||||
|
super(getEmptyFields(height), rowId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Field[] getEmptyFields(int height) {
|
||||||
|
return new Field[] { new EmptyTextField(height, 0, 0, 0) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to track all row heights for a given {@link MultiRowLayout}. Multiple instances
|
||||||
|
* of this class can be merged to create a total collection of row heights for more than one
|
||||||
|
* {@link MultiRowLayout}, such as is done for the diff tool. The merged row heights
|
||||||
|
* represent the total number of rows possible as well as the maximum possible height for a
|
||||||
|
* given row.
|
||||||
|
*/
|
||||||
|
public static class RowHeights {
|
||||||
|
|
||||||
|
private Map<Integer, Integer> heightsByRow = new HashMap<>();
|
||||||
|
private int largestRow;
|
||||||
|
|
||||||
|
void addHeight(RowLayout layout) {
|
||||||
|
int row = layout.getRowID();
|
||||||
|
int rowHeight = layout.getHeight();
|
||||||
|
int totalHeight = heightsByRow.computeIfAbsent(row, k -> 0);
|
||||||
|
heightsByRow.put(row, totalHeight + rowHeight);
|
||||||
|
largestRow = Math.max(row, largestRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getHeight(int row) {
|
||||||
|
return heightsByRow.computeIfAbsent(row, k -> 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getRowCount() {
|
||||||
|
return largestRow + 1; // +1 for index vs count
|
||||||
|
}
|
||||||
|
|
||||||
|
public void merge(RowHeights other) {
|
||||||
|
|
||||||
|
int myRowCount = getRowCount();
|
||||||
|
int otherRowCount = other.getRowCount();
|
||||||
|
int rowCount = Math.max(myRowCount, otherRowCount);
|
||||||
|
|
||||||
|
for (int row = 0; row < rowCount; row++) {
|
||||||
|
int myRowHeight = heightsByRow.computeIfAbsent(row, k -> 0);
|
||||||
|
int otherRowHeight = other.getHeight(row);
|
||||||
|
int largestRowHeight = Math.max(myRowHeight, otherRowHeight);
|
||||||
|
heightsByRow.put(row, largestRowHeight);
|
||||||
|
largestRow = Math.max(row, largestRow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -16,6 +16,7 @@
|
|||||||
package docking.widgets.fieldpanel.support;
|
package docking.widgets.fieldpanel.support;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
@ -445,4 +446,9 @@ public class RowLayout implements Layout {
|
|||||||
int index = this.findAppropriateFieldIndex(x, y);
|
int index = this.findAppropriateFieldIndex(x, y);
|
||||||
return index >= 0 ? index : 0;
|
return index >= 0 ? index : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Arrays.toString(fields);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user