mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Minor refactor of table address retrieval and some options constants
This commit is contained in:
parent
7ddd8665b7
commit
5d58d61506
15 changed files with 301 additions and 196 deletions
|
@ -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,6 +18,7 @@ package ghidra;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
|
||||||
import generic.theme.GColor;
|
import generic.theme.GColor;
|
||||||
|
import ghidra.app.util.SearchConstants;
|
||||||
import ghidra.framework.options.Options;
|
import ghidra.framework.options.Options;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,13 +83,17 @@ public interface GhidraOptions {
|
||||||
/**
|
/**
|
||||||
* Option for the max number of hits found in a search; the search
|
* Option for the max number of hits found in a search; the search
|
||||||
* stops when it reaches this limit.
|
* stops when it reaches this limit.
|
||||||
|
* @deprecated use {@link SearchConstants#SEARCH_LIMIT_NAME}
|
||||||
*/
|
*/
|
||||||
final String OPTION_SEARCH_LIMIT = "Search Limit";
|
@Deprecated
|
||||||
|
final String OPTION_SEARCH_LIMIT = SearchConstants.SEARCH_LIMIT_NAME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options title the search category
|
* Options title the search category
|
||||||
|
* @deprecated use {@link SearchConstants#SEARCH_OPTION_NAME}
|
||||||
*/
|
*/
|
||||||
final String OPTION_SEARCH_TITLE = "Search";
|
@Deprecated(since = "11.3", forRemoval = true)
|
||||||
|
final String OPTION_SEARCH_TITLE = SearchConstants.SEARCH_OPTION_NAME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Category name for the "Auto Analysis" options.
|
* Category name for the "Auto Analysis" options.
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -39,8 +39,10 @@ import ghidra.util.task.TaskMonitor;
|
||||||
*/
|
*/
|
||||||
public class AddressRangeTableModel extends GhidraProgramTableModel<AddressRangeInfo> {
|
public class AddressRangeTableModel extends GhidraProgramTableModel<AddressRangeInfo> {
|
||||||
|
|
||||||
private ProgramSelection selection;
|
private static final int MIN_ADDRESS_COLUMN_INDEX = 0;
|
||||||
private static final int MAX_ADDRESS_COLUMN_INDEX = 1;
|
private static final int MAX_ADDRESS_COLUMN_INDEX = 1;
|
||||||
|
|
||||||
|
private ProgramSelection selection;
|
||||||
private int resultsLimit;
|
private int resultsLimit;
|
||||||
private long minLength;
|
private long minLength;
|
||||||
|
|
||||||
|
@ -52,24 +54,6 @@ public class AddressRangeTableModel extends GhidraProgramTableModel<AddressRange
|
||||||
this.minLength = minLength;
|
this.minLength = minLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProgramLocation getProgramLocation(int modelRow, int modelColumn) {
|
|
||||||
AddressRangeInfo rangeInfo = getRowObject(modelRow);
|
|
||||||
if (modelColumn == MAX_ADDRESS_COLUMN_INDEX) {
|
|
||||||
return new ProgramLocation(program, rangeInfo.max());
|
|
||||||
}
|
|
||||||
return new ProgramLocation(program, rangeInfo.min());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProgramSelection getProgramSelection(int[] modelRows) {
|
|
||||||
AddressSet ranges = new AddressSet();
|
|
||||||
for (AddressRangeInfo rangeInfo : getRowObjects(modelRows)) {
|
|
||||||
ranges.addRange(program, rangeInfo.min(), rangeInfo.max());
|
|
||||||
}
|
|
||||||
return new ProgramSelection(program.getAddressFactory(), ranges);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doLoad(Accumulator<AddressRangeInfo> accumulator, TaskMonitor monitor)
|
protected void doLoad(Accumulator<AddressRangeInfo> accumulator, TaskMonitor monitor)
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
|
@ -140,6 +124,42 @@ public class AddressRangeTableModel extends GhidraProgramTableModel<AddressRange
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProgramLocation getProgramLocation(int modelRow, int modelColumn) {
|
||||||
|
AddressRangeInfo rangeInfo = getRowObject(modelRow);
|
||||||
|
if (modelColumn == MAX_ADDRESS_COLUMN_INDEX) {
|
||||||
|
return new ProgramLocation(program, rangeInfo.max());
|
||||||
|
}
|
||||||
|
return new ProgramLocation(program, rangeInfo.min());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProgramSelection getProgramSelection(int[] modelRows) {
|
||||||
|
AddressSet ranges = new AddressSet();
|
||||||
|
for (AddressRangeInfo rangeInfo : getRowObjects(modelRows)) {
|
||||||
|
ranges.addRange(program, rangeInfo.min(), rangeInfo.max());
|
||||||
|
}
|
||||||
|
return new ProgramSelection(ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Address getAddress(int modelRow) {
|
||||||
|
AddressRangeInfo rangeInfo = getRowObject(modelRow);
|
||||||
|
return rangeInfo.min();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Address getAddress(int modelRow, int modelColumn) {
|
||||||
|
AddressRangeInfo rangeInfo = getRowObject(modelRow);
|
||||||
|
if (modelColumn == MIN_ADDRESS_COLUMN_INDEX) {
|
||||||
|
return rangeInfo.min();
|
||||||
|
}
|
||||||
|
else if (modelColumn == MAX_ADDRESS_COLUMN_INDEX) {
|
||||||
|
return rangeInfo.max();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private class MinAddressTableColumn
|
private class MinAddressTableColumn
|
||||||
extends AbstractDynamicTableColumn<AddressRangeInfo, Address, Object> {
|
extends AbstractDynamicTableColumn<AddressRangeInfo, Address, Object> {
|
||||||
|
|
||||||
|
@ -235,20 +255,19 @@ public class AddressRangeTableModel extends GhidraProgramTableModel<AddressRange
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NumRefsFromTableColumn
|
private class NumRefsFromTableColumn
|
||||||
extends AbstractDynamicTableColumn<AddressRangeInfo, Integer, Object> {
|
extends AbstractDynamicTableColumn<AddressRangeInfo, Integer, Object> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getColumnName() {
|
public String getColumnName() {
|
||||||
return "From References";
|
return "From References";
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getValue(AddressRangeInfo rangeInfo, Settings settings, Object data,
|
|
||||||
ServiceProvider services) throws IllegalArgumentException {
|
|
||||||
return rangeInfo.numRefsFrom();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getValue(AddressRangeInfo rangeInfo, Settings settings, Object data,
|
||||||
|
ServiceProvider services) throws IllegalArgumentException {
|
||||||
|
return rangeInfo.numRefsFrom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,7 +17,6 @@ package ghidra.app.plugin.core.gotoquery;
|
||||||
|
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
|
|
||||||
import ghidra.GhidraOptions;
|
|
||||||
import ghidra.app.CorePluginPackage;
|
import ghidra.app.CorePluginPackage;
|
||||||
import ghidra.app.events.*;
|
import ghidra.app.events.*;
|
||||||
import ghidra.app.nav.*;
|
import ghidra.app.nav.*;
|
||||||
|
@ -67,7 +66,7 @@ public final class GoToServicePlugin extends ProgramPlugin {
|
||||||
Options opt = tool.getOptions(SearchConstants.SEARCH_OPTION_NAME);
|
Options opt = tool.getOptions(SearchConstants.SEARCH_OPTION_NAME);
|
||||||
|
|
||||||
// we register this option here, since the other search plugins all depend on this service
|
// we register this option here, since the other search plugins all depend on this service
|
||||||
opt.registerOption(GhidraOptions.OPTION_SEARCH_LIMIT,
|
opt.registerOption(SearchConstants.SEARCH_LIMIT_NAME,
|
||||||
SearchConstants.DEFAULT_SEARCH_LIMIT, null,
|
SearchConstants.DEFAULT_SEARCH_LIMIT, null,
|
||||||
"The maximum number of search results.");
|
"The maximum number of search results.");
|
||||||
|
|
||||||
|
@ -90,7 +89,7 @@ public final class GoToServicePlugin extends ProgramPlugin {
|
||||||
int getMaxHits() {
|
int getMaxHits() {
|
||||||
Options opt = tool.getOptions(SearchConstants.SEARCH_OPTION_NAME);
|
Options opt = tool.getOptions(SearchConstants.SEARCH_OPTION_NAME);
|
||||||
int maxSearchHits =
|
int maxSearchHits =
|
||||||
opt.getInt(GhidraOptions.OPTION_SEARCH_LIMIT, SearchConstants.DEFAULT_SEARCH_LIMIT);
|
opt.getInt(SearchConstants.SEARCH_LIMIT_NAME, SearchConstants.DEFAULT_SEARCH_LIMIT);
|
||||||
|
|
||||||
return maxSearchHits;
|
return maxSearchHits;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -23,6 +23,7 @@ import ghidra.GhidraOptions;
|
||||||
import ghidra.app.nav.Navigatable;
|
import ghidra.app.nav.Navigatable;
|
||||||
import ghidra.app.services.*;
|
import ghidra.app.services.*;
|
||||||
import ghidra.app.util.ListingHighlightProvider;
|
import ghidra.app.util.ListingHighlightProvider;
|
||||||
|
import ghidra.app.util.SearchConstants;
|
||||||
import ghidra.app.util.viewer.field.ListingField;
|
import ghidra.app.util.viewer.field.ListingField;
|
||||||
import ghidra.app.util.viewer.proxy.ProxyObj;
|
import ghidra.app.util.viewer.proxy.ProxyObj;
|
||||||
import ghidra.framework.options.OptionsChangeListener;
|
import ghidra.framework.options.OptionsChangeListener;
|
||||||
|
@ -39,7 +40,7 @@ class LocationReferencesHighlighter {
|
||||||
private static final String MARKER_SET_DESCRIPTION = "Shows the location of references " +
|
private static final String MARKER_SET_DESCRIPTION = "Shows the location of references " +
|
||||||
"currently displayed in the Location References window.";
|
"currently displayed in the Location References window.";
|
||||||
|
|
||||||
private static final String OPTIONS_TITLE = GhidraOptions.OPTION_SEARCH_TITLE;
|
private static final String OPTIONS_TITLE = SearchConstants.SEARCH_OPTION_NAME;
|
||||||
private static final String HIGHLIGHT_COLOR_KEY =
|
private static final String HIGHLIGHT_COLOR_KEY =
|
||||||
"Reference Search" + GhidraOptions.DELIMITER + "Highlight Match Color";
|
"Reference Search" + GhidraOptions.DELIMITER + "Highlight Match Color";
|
||||||
private static final String HIGHLIGHT_COLOR_DESCRIPTION =
|
private static final String HIGHLIGHT_COLOR_DESCRIPTION =
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -200,14 +200,28 @@ public class FunctionReachabilityTableModel
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProgramLocation getProgramLocation(int row, int column) {
|
public Address getAddress(int modelRow, int modelColumn) {
|
||||||
FunctionReachabilityResult result = getRowObject(row);
|
FunctionReachabilityResult result = getRowObject(modelColumn);
|
||||||
if (column == FROM_FUNCTION_COLUMN) {
|
if (modelColumn == FROM_FUNCTION_COLUMN) {
|
||||||
|
Function function = result.getFromFunction();
|
||||||
|
return function.getEntryPoint();
|
||||||
|
}
|
||||||
|
else if (modelColumn == TO_FUNCTION_COLUMN) {
|
||||||
|
Function function = result.getToFunction();
|
||||||
|
return function.getEntryPoint();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProgramLocation getProgramLocation(int modelRow, int modelColumn) {
|
||||||
|
FunctionReachabilityResult result = getRowObject(modelRow);
|
||||||
|
if (modelColumn == FROM_FUNCTION_COLUMN) {
|
||||||
Function function = result.getFromFunction();
|
Function function = result.getFromFunction();
|
||||||
Address address = function.getEntryPoint();
|
Address address = function.getEntryPoint();
|
||||||
return new ProgramLocation(getProgram(), address);
|
return new ProgramLocation(getProgram(), address);
|
||||||
}
|
}
|
||||||
else if (column == TO_FUNCTION_COLUMN) {
|
else if (modelColumn == TO_FUNCTION_COLUMN) {
|
||||||
Function function = result.getToFunction();
|
Function function = result.getToFunction();
|
||||||
Address address = function.getEntryPoint();
|
Address address = function.getEntryPoint();
|
||||||
return new ProgramLocation(getProgram(), address);
|
return new ProgramLocation(getProgram(), address);
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.searchtext;
|
package ghidra.app.plugin.core.searchtext;
|
||||||
|
|
||||||
import ghidra.GhidraOptions;
|
|
||||||
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
|
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
|
||||||
import ghidra.app.util.SearchConstants;
|
import ghidra.app.util.SearchConstants;
|
||||||
import ghidra.app.util.query.ProgramLocationPreviewTableModel;
|
import ghidra.app.util.query.ProgramLocationPreviewTableModel;
|
||||||
|
@ -51,7 +50,7 @@ public abstract class AbstractSearchTableModel extends ProgramLocationPreviewTab
|
||||||
this.options = options;
|
this.options = options;
|
||||||
Options opt = tool.getOptions(SearchConstants.SEARCH_OPTION_NAME);
|
Options opt = tool.getOptions(SearchConstants.SEARCH_OPTION_NAME);
|
||||||
searchLimit =
|
searchLimit =
|
||||||
opt.getInt(GhidraOptions.OPTION_SEARCH_LIMIT, SearchConstants.DEFAULT_SEARCH_LIMIT);
|
opt.getInt(SearchConstants.SEARCH_LIMIT_NAME, SearchConstants.DEFAULT_SEARCH_LIMIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -31,7 +31,6 @@ import docking.tool.ToolConstants;
|
||||||
import docking.widgets.fieldpanel.support.Highlight;
|
import docking.widgets.fieldpanel.support.Highlight;
|
||||||
import docking.widgets.table.threaded.*;
|
import docking.widgets.table.threaded.*;
|
||||||
import generic.theme.GIcon;
|
import generic.theme.GIcon;
|
||||||
import ghidra.GhidraOptions;
|
|
||||||
import ghidra.app.CorePluginPackage;
|
import ghidra.app.CorePluginPackage;
|
||||||
import ghidra.app.context.*;
|
import ghidra.app.context.*;
|
||||||
import ghidra.app.nav.Navigatable;
|
import ghidra.app.nav.Navigatable;
|
||||||
|
@ -423,7 +422,7 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
|
||||||
@Override
|
@Override
|
||||||
public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
|
public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
|
||||||
Object newValue) {
|
Object newValue) {
|
||||||
if (optionName.equals(GhidraOptions.OPTION_SEARCH_LIMIT)) {
|
if (optionName.equals(SearchConstants.SEARCH_LIMIT_NAME)) {
|
||||||
int newSearchLimit = ((Integer) newValue).intValue();
|
int newSearchLimit = ((Integer) newValue).intValue();
|
||||||
if (newSearchLimit <= 0) {
|
if (newSearchLimit <= 0) {
|
||||||
throw new OptionsVetoException("Search limit must be greater than 0");
|
throw new OptionsVetoException("Search limit must be greater than 0");
|
||||||
|
@ -450,7 +449,7 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
|
||||||
"The search result highlight color for the currently selected match");
|
"The search result highlight color for the currently selected match");
|
||||||
|
|
||||||
searchLimit =
|
searchLimit =
|
||||||
opt.getInt(GhidraOptions.OPTION_SEARCH_LIMIT, SearchConstants.DEFAULT_SEARCH_LIMIT);
|
opt.getInt(SearchConstants.SEARCH_LIMIT_NAME, SearchConstants.DEFAULT_SEARCH_LIMIT);
|
||||||
|
|
||||||
doHighlight = opt.getBoolean(SearchConstants.SEARCH_HIGHLIGHT_NAME, true);
|
doHighlight = opt.getBoolean(SearchConstants.SEARCH_HIGHLIGHT_NAME, true);
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -32,6 +32,12 @@ public interface SearchConstants {
|
||||||
*/
|
*/
|
||||||
public static final String SEARCH_OPTION_NAME = "Search";
|
public static final String SEARCH_OPTION_NAME = "Search";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option for the max number of hits found in a search; the search
|
||||||
|
* stops when it reaches this limit.
|
||||||
|
*/
|
||||||
|
public static final String SEARCH_LIMIT_NAME = "Search Limit";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Option name for whether to highlight search results.
|
* Option name for whether to highlight search results.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,7 +19,6 @@ import java.util.*;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import ghidra.GhidraOptions;
|
|
||||||
import ghidra.app.nav.Navigatable;
|
import ghidra.app.nav.Navigatable;
|
||||||
import ghidra.app.plugin.core.gotoquery.GoToQueryResultsTableModel;
|
import ghidra.app.plugin.core.gotoquery.GoToQueryResultsTableModel;
|
||||||
import ghidra.app.plugin.core.navigation.NavigationOptions;
|
import ghidra.app.plugin.core.navigation.NavigationOptions;
|
||||||
|
@ -75,7 +74,7 @@ public class GoToQuery {
|
||||||
|
|
||||||
Options options = plugin.getTool().getOptions(SearchConstants.SEARCH_OPTION_NAME);
|
Options options = plugin.getTool().getOptions(SearchConstants.SEARCH_OPTION_NAME);
|
||||||
this.maxHits =
|
this.maxHits =
|
||||||
options.getInt(GhidraOptions.OPTION_SEARCH_LIMIT, SearchConstants.DEFAULT_SEARCH_LIMIT);
|
options.getInt(SearchConstants.SEARCH_LIMIT_NAME, SearchConstants.DEFAULT_SEARCH_LIMIT);
|
||||||
this.fromAddress = fromAddr;
|
this.fromAddress = fromAddr;
|
||||||
this.monitor = monitor;
|
this.monitor = monitor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.features.base.memsearch.gui;
|
package ghidra.features.base.memsearch.gui;
|
||||||
|
|
||||||
import static ghidra.GhidraOptions.*;
|
|
||||||
import static ghidra.app.util.SearchConstants.*;
|
import static ghidra.app.util.SearchConstants.*;
|
||||||
|
|
||||||
import ghidra.GhidraOptions;
|
import ghidra.GhidraOptions;
|
||||||
|
@ -113,7 +112,7 @@ public class MemorySearchOptions {
|
||||||
private void searchOptionsChanged(ToolOptions options, String optionName, Object oldValue,
|
private void searchOptionsChanged(ToolOptions options, String optionName, Object oldValue,
|
||||||
Object newValue) {
|
Object newValue) {
|
||||||
|
|
||||||
if (optionName.equals(OPTION_SEARCH_LIMIT)) {
|
if (optionName.equals(SEARCH_LIMIT_NAME)) {
|
||||||
int limit = (int) newValue;
|
int limit = (int) newValue;
|
||||||
if (limit <= 0) {
|
if (limit <= 0) {
|
||||||
throw new OptionsVetoException("Search limit must be greater than 0");
|
throw new OptionsVetoException("Search limit must be greater than 0");
|
||||||
|
@ -125,7 +124,7 @@ public class MemorySearchOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadSearchOptions(ToolOptions options) {
|
private void loadSearchOptions(ToolOptions options) {
|
||||||
searchLimit = options.getInt(OPTION_SEARCH_LIMIT, DEFAULT_SEARCH_LIMIT);
|
searchLimit = options.getInt(SEARCH_LIMIT_NAME, DEFAULT_SEARCH_LIMIT);
|
||||||
highlightMatches = options.getBoolean(SEARCH_HIGHLIGHT_NAME, true);
|
highlightMatches = options.getBoolean(SEARCH_HIGHLIGHT_NAME, true);
|
||||||
autoRestrictSelection = options.getBoolean(AUTO_RESTRICT_SELECTION, true);
|
autoRestrictSelection = options.getBoolean(AUTO_RESTRICT_SELECTION, true);
|
||||||
prepopulateSearch = options.getBoolean(PRE_POPULATE_MEM_SEARCH, true);
|
prepopulateSearch = options.getBoolean(PRE_POPULATE_MEM_SEARCH, true);
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -15,17 +15,15 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.util.table;
|
package ghidra.util.table;
|
||||||
|
|
||||||
import docking.widgets.table.*;
|
|
||||||
import ghidra.docking.settings.Settings;
|
|
||||||
import ghidra.framework.plugintool.ServiceProvider;
|
import ghidra.framework.plugintool.ServiceProvider;
|
||||||
import ghidra.program.model.address.Address;
|
|
||||||
import ghidra.program.model.address.AddressSet;
|
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.util.ProgramLocation;
|
|
||||||
import ghidra.program.util.ProgramSelection;
|
|
||||||
import ghidra.util.table.field.*;
|
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is now just a shell left in place to not break external clients.
|
||||||
|
*
|
||||||
|
* @param <ROW_TYPE> the row type
|
||||||
|
*/
|
||||||
public abstract class AddressBasedTableModel<ROW_TYPE> extends GhidraProgramTableModel<ROW_TYPE> {
|
public abstract class AddressBasedTableModel<ROW_TYPE> extends GhidraProgramTableModel<ROW_TYPE> {
|
||||||
|
|
||||||
public AddressBasedTableModel(String title, ServiceProvider serviceProvider, Program program,
|
public AddressBasedTableModel(String title, ServiceProvider serviceProvider, Program program,
|
||||||
|
@ -37,100 +35,4 @@ public abstract class AddressBasedTableModel<ROW_TYPE> extends GhidraProgramTabl
|
||||||
TaskMonitor monitor, boolean loadIncrementally) {
|
TaskMonitor monitor, boolean loadIncrementally) {
|
||||||
super(title, serviceProvider, program, monitor, loadIncrementally);
|
super(title, serviceProvider, program, monitor, loadIncrementally);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Address getAddress(int row);
|
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
|
||||||
// We create an untyped column descriptor. However, we are assigning it to a typed variable,
|
|
||||||
// which guarantees that we only put homogeneous objects into the descriptor.
|
|
||||||
@Override
|
|
||||||
protected TableColumnDescriptor<ROW_TYPE> createTableColumnDescriptor() {
|
|
||||||
TableColumnDescriptor<ROW_TYPE> descriptor = new TableColumnDescriptor();
|
|
||||||
|
|
||||||
descriptor.addVisibleColumn(
|
|
||||||
DiscoverableTableUtils.adaptColumForModel(this, new AddressTableColumn()), 1, true);
|
|
||||||
descriptor.addVisibleColumn(
|
|
||||||
DiscoverableTableUtils.adaptColumForModel(this, new LabelTableColumn()));
|
|
||||||
descriptor.addVisibleColumn(
|
|
||||||
DiscoverableTableUtils.adaptColumForModel(this, new CodeUnitTableColumn()));
|
|
||||||
|
|
||||||
return descriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProgramLocation getProgramLocation(int row, int column) {
|
|
||||||
if (row < 0 || row >= filteredData.size()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ROW_TYPE rowObject = filteredData.get(row);
|
|
||||||
DynamicTableColumn<ROW_TYPE, ?, ?> tableColumn = getColumn(column);
|
|
||||||
if (tableColumn instanceof ProgramLocationTableColumn<?, ?>) {
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") // we checked
|
|
||||||
ProgramLocationTableColumn<ROW_TYPE, ?> programField =
|
|
||||||
(ProgramLocationTableColumn<ROW_TYPE, ?>) tableColumn;
|
|
||||||
ProgramLocation loc = programField.getProgramLocation(rowObject,
|
|
||||||
getColumnSettings(column), getProgram(), serviceProvider);
|
|
||||||
if (loc != null) {
|
|
||||||
return loc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Address address = getAddress(row, column);
|
|
||||||
if (address != null) {
|
|
||||||
return new ProgramLocation(getProgram(), address);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Address getAddress(int row, int column) {
|
|
||||||
DynamicTableColumn<ROW_TYPE, ?, ?> tableColumn = getColumn(column);
|
|
||||||
|
|
||||||
if (tableColumn instanceof ProgramLocationTableColumn<?, ?>) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
// we checked
|
|
||||||
ProgramLocationTableColumn<ROW_TYPE, ?> programLocationColumn =
|
|
||||||
(ProgramLocationTableColumn<ROW_TYPE, ?>) tableColumn;
|
|
||||||
Settings settings = getColumnSettings(column);
|
|
||||||
ROW_TYPE rowObject = filteredData.get(row);
|
|
||||||
Object value =
|
|
||||||
programLocationColumn.getValue(rowObject, settings, getProgram(), serviceProvider);
|
|
||||||
if (value instanceof Address) {
|
|
||||||
return (Address) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value instanceof ProgramLocation) {
|
|
||||||
ProgramLocation programLocation = (ProgramLocation) value;
|
|
||||||
return programLocation.getByteAddress();
|
|
||||||
}
|
|
||||||
|
|
||||||
ProgramLocation location = programLocationColumn.getProgramLocation(rowObject, settings,
|
|
||||||
getProgram(), serviceProvider);
|
|
||||||
if (location != null) {
|
|
||||||
return location.getByteAddress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ROW_TYPE storageValue = filteredData.get(row);
|
|
||||||
Object columnValueForRow = getColumnValueForRow(storageValue, column);
|
|
||||||
if (columnValueForRow instanceof Address) {
|
|
||||||
return (Address) columnValueForRow;
|
|
||||||
}
|
|
||||||
return getAddress(row); // TODO Perhaps this should return null?
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProgramSelection getProgramSelection(int[] rows) {
|
|
||||||
AddressSet addressSet = new AddressSet();
|
|
||||||
for (int element : rows) {
|
|
||||||
Address addr = getAddress(element);
|
|
||||||
if (addr.isMemoryAddress()) {
|
|
||||||
addressSet.addRange(addr, addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ProgramSelection(addressSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -15,10 +15,16 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.util.table;
|
package ghidra.util.table;
|
||||||
|
|
||||||
|
import docking.widgets.table.*;
|
||||||
import docking.widgets.table.threaded.ThreadedTableModel;
|
import docking.widgets.table.threaded.ThreadedTableModel;
|
||||||
|
import ghidra.docking.settings.Settings;
|
||||||
import ghidra.framework.plugintool.ServiceProvider;
|
import ghidra.framework.plugintool.ServiceProvider;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.address.AddressSet;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.program.util.ProgramLocation;
|
||||||
|
import ghidra.program.util.ProgramSelection;
|
||||||
|
import ghidra.util.table.field.*;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
public abstract class GhidraProgramTableModel<ROW_TYPE>
|
public abstract class GhidraProgramTableModel<ROW_TYPE>
|
||||||
|
@ -37,6 +43,23 @@ public abstract class GhidraProgramTableModel<ROW_TYPE>
|
||||||
this.program = program;
|
this.program = program;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
|
// We create an untyped column descriptor. However, we are assigning it to a typed variable,
|
||||||
|
// which guarantees that we only put homogeneous objects into the descriptor.
|
||||||
|
@Override
|
||||||
|
protected TableColumnDescriptor<ROW_TYPE> createTableColumnDescriptor() {
|
||||||
|
TableColumnDescriptor<ROW_TYPE> descriptor = new TableColumnDescriptor();
|
||||||
|
|
||||||
|
descriptor.addVisibleColumn(
|
||||||
|
DiscoverableTableUtils.adaptColumForModel(this, new AddressTableColumn()), 1, true);
|
||||||
|
descriptor.addVisibleColumn(
|
||||||
|
DiscoverableTableUtils.adaptColumForModel(this, new LabelTableColumn()));
|
||||||
|
descriptor.addVisibleColumn(
|
||||||
|
DiscoverableTableUtils.adaptColumForModel(this, new CodeUnitTableColumn()));
|
||||||
|
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
public void setProgram(Program program) {
|
public void setProgram(Program program) {
|
||||||
Program originalProgram = this.program;
|
Program originalProgram = this.program;
|
||||||
this.program = program;
|
this.program = program;
|
||||||
|
@ -66,14 +89,155 @@ public abstract class GhidraProgramTableModel<ROW_TYPE>
|
||||||
return getProgram();
|
return getProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
// most subclasses will override this to return an address
|
|
||||||
public Address getAddress(int row) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
program = null;
|
program = null;
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an address for the given row and column.
|
||||||
|
* @param modelRow the model row
|
||||||
|
* @param modelColumn the column row
|
||||||
|
* @return the address
|
||||||
|
*/
|
||||||
|
public Address getAddress(int modelRow, int modelColumn) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try to find an address for the given cell.
|
||||||
|
//
|
||||||
|
// 1) Prefer columns that have a ProgramLocation, as they are already used for navigation.
|
||||||
|
//
|
||||||
|
ROW_TYPE rowObject = filteredData.get(modelRow);
|
||||||
|
DynamicTableColumn<ROW_TYPE, ?, ?> tableColumn = getColumn(modelColumn);
|
||||||
|
if (tableColumn instanceof ProgramLocationTableColumn<?, ?>) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// we checked
|
||||||
|
ProgramLocationTableColumn<ROW_TYPE, ?> programLocationColumn =
|
||||||
|
(ProgramLocationTableColumn<ROW_TYPE, ?>) tableColumn;
|
||||||
|
Settings settings = getColumnSettings(modelColumn);
|
||||||
|
Object value =
|
||||||
|
programLocationColumn.getValue(rowObject, settings, getProgram(), serviceProvider);
|
||||||
|
if (value instanceof Address) {
|
||||||
|
return (Address) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value instanceof ProgramLocation) {
|
||||||
|
ProgramLocation programLocation = (ProgramLocation) value;
|
||||||
|
return programLocation.getByteAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgramLocation location = programLocationColumn.getProgramLocation(rowObject, settings,
|
||||||
|
getProgram(), serviceProvider);
|
||||||
|
if (location != null) {
|
||||||
|
return location.getByteAddress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 2) See if the given cell value is an Address
|
||||||
|
//
|
||||||
|
Object columnValue = getColumnValueForRow(rowObject, modelColumn);
|
||||||
|
if (columnValue instanceof Address) {
|
||||||
|
return (Address) columnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 3) Check to see if we can get an Address directly from my row object
|
||||||
|
//
|
||||||
|
Address address = getAddress(modelRow);
|
||||||
|
if (address != null) {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 4) Check for the case where we are using a mapped column that converted the current row
|
||||||
|
// object into an Address row object.
|
||||||
|
//
|
||||||
|
Object mappedRowObject = getMappedRowObject(tableColumn, rowObject, modelColumn);
|
||||||
|
if (mappedRowObject instanceof Address) {
|
||||||
|
return (Address) mappedRowObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the best Address for the given row.
|
||||||
|
* <P>
|
||||||
|
* Implementation Note: this class will only return an Address if this model's row type is
|
||||||
|
* Address. Clients that know how to get an Address for a given row should override this
|
||||||
|
* method.
|
||||||
|
* @param modelRow the row
|
||||||
|
* @return the Address or null
|
||||||
|
*/
|
||||||
|
public Address getAddress(int modelRow) {
|
||||||
|
ROW_TYPE rowObject = filteredData.get(modelRow);
|
||||||
|
if (rowObject instanceof Address) {
|
||||||
|
return (Address) rowObject;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the given column supports row mapping, then use that column to get the mapped row. In
|
||||||
|
* this case, our table may have a row object, like Function, that the column maps to another
|
||||||
|
* type that it needs, like Address.
|
||||||
|
*
|
||||||
|
* @param tableColumn the table column
|
||||||
|
* @param currentRowObject the table's actual non-mapped row value
|
||||||
|
* @param columnIndex the column index
|
||||||
|
* @return the mapped row value or null
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Object getMappedRowObject(DynamicTableColumn<ROW_TYPE, ?, ?> tableColumn,
|
||||||
|
ROW_TYPE currentRowObject, int columnIndex) {
|
||||||
|
|
||||||
|
if (tableColumn instanceof MappedTableColumn) {
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
MappedTableColumn mappedColumn = (MappedTableColumn) tableColumn;
|
||||||
|
return mappedColumn.map(currentRowObject, getProgram(), serviceProvider);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProgramLocation getProgramLocation(int modelRow, int modelColumn) {
|
||||||
|
if (modelRow < 0 || modelRow >= filteredData.size()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ROW_TYPE rowObject = filteredData.get(modelRow);
|
||||||
|
DynamicTableColumn<ROW_TYPE, ?, ?> tableColumn = getColumn(modelColumn);
|
||||||
|
if (tableColumn instanceof ProgramLocationTableColumn<?, ?>) {
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked") // we checked
|
||||||
|
ProgramLocationTableColumn<ROW_TYPE, ?> programField =
|
||||||
|
(ProgramLocationTableColumn<ROW_TYPE, ?>) tableColumn;
|
||||||
|
ProgramLocation loc = programField.getProgramLocation(rowObject,
|
||||||
|
getColumnSettings(modelColumn), getProgram(), serviceProvider);
|
||||||
|
if (loc != null) {
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Address address = getAddress(modelRow, modelColumn);
|
||||||
|
if (address != null) {
|
||||||
|
return new ProgramLocation(getProgram(), address);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProgramSelection getProgramSelection(int[] modelRows) {
|
||||||
|
AddressSet addressSet = new AddressSet();
|
||||||
|
for (int element : modelRows) {
|
||||||
|
Address addr = getAddress(element);
|
||||||
|
if (addr.isMemoryAddress()) {
|
||||||
|
addressSet.addRange(addr, addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ProgramSelection(addressSet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ import docking.widgets.combobox.GhidraComboBox;
|
||||||
import docking.widgets.table.GTable;
|
import docking.widgets.table.GTable;
|
||||||
import docking.widgets.table.threaded.GThreadedTablePanel;
|
import docking.widgets.table.threaded.GThreadedTablePanel;
|
||||||
import generic.test.TestUtils;
|
import generic.test.TestUtils;
|
||||||
import ghidra.GhidraOptions;
|
|
||||||
import ghidra.app.cmd.data.CreateDataCmd;
|
import ghidra.app.cmd.data.CreateDataCmd;
|
||||||
import ghidra.app.cmd.label.AddLabelCmd;
|
import ghidra.app.cmd.label.AddLabelCmd;
|
||||||
import ghidra.app.cmd.label.CreateNamespacesCmd;
|
import ghidra.app.cmd.label.CreateNamespacesCmd;
|
||||||
|
@ -570,7 +569,7 @@ public class GoToAddressLabelPluginTest extends AbstractGhidraHeadedIntegrationT
|
||||||
public void testQueryResultsMaxHitsDynamicFound() throws Exception {
|
public void testQueryResultsMaxHitsDynamicFound() throws Exception {
|
||||||
loadProgram("x86");
|
loadProgram("x86");
|
||||||
Options opt = plugin.getTool().getOptions(SearchConstants.SEARCH_OPTION_NAME);
|
Options opt = plugin.getTool().getOptions(SearchConstants.SEARCH_OPTION_NAME);
|
||||||
opt.setInt(GhidraOptions.OPTION_SEARCH_LIMIT, 20);
|
opt.setInt(SearchConstants.SEARCH_LIMIT_NAME, 20);
|
||||||
|
|
||||||
setText("L*");
|
setText("L*");
|
||||||
performOkCallback();
|
performOkCallback();
|
||||||
|
@ -582,7 +581,7 @@ public class GoToAddressLabelPluginTest extends AbstractGhidraHeadedIntegrationT
|
||||||
public void testQueryResultsMaxHitsDefinedFound() throws Exception {
|
public void testQueryResultsMaxHitsDefinedFound() throws Exception {
|
||||||
loadProgram("x86");
|
loadProgram("x86");
|
||||||
Options opt = plugin.getTool().getOptions(SearchConstants.SEARCH_OPTION_NAME);
|
Options opt = plugin.getTool().getOptions(SearchConstants.SEARCH_OPTION_NAME);
|
||||||
opt.setInt(GhidraOptions.OPTION_SEARCH_LIMIT, 5);
|
opt.setInt(SearchConstants.SEARCH_LIMIT_NAME, 5);
|
||||||
|
|
||||||
createLabel("1006960", "abc1");
|
createLabel("1006960", "abc1");
|
||||||
createLabel("1006961", "abc2");
|
createLabel("1006961", "abc2");
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -124,16 +124,16 @@ public class MappedTableColumn<ROW_TYPE, EXPECTED_ROW_TYPE, COLUMN_TYPE, DATA_SO
|
||||||
public COLUMN_TYPE getValue(ROW_TYPE rowObject, Settings settings, DATA_SOURCE data,
|
public COLUMN_TYPE getValue(ROW_TYPE rowObject, Settings settings, DATA_SOURCE data,
|
||||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||||
|
|
||||||
if (rowObject == null) {
|
EXPECTED_ROW_TYPE mappedRowObject = map(rowObject, data, serviceProvider);
|
||||||
// can happen when the model is cleared out from under Swing
|
return tableColumn.getValue(mappedRowObject, settings, data, serviceProvider);
|
||||||
return null;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
EXPECTED_ROW_TYPE mappedObject = mapper.map(rowObject, data, serviceProvider);
|
public EXPECTED_ROW_TYPE map(ROW_TYPE rowObject, DATA_SOURCE data,
|
||||||
if (mappedObject == null) {
|
ServiceProvider serviceProvider) {
|
||||||
return null; // some mappers have null data
|
if (rowObject == null) {
|
||||||
|
return null;// can happen when the model is cleared out from under Swing
|
||||||
}
|
}
|
||||||
return tableColumn.getValue(mappedObject, settings, data, serviceProvider);
|
return mapper.map(rowObject, data, serviceProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -27,10 +27,10 @@ import docking.ComponentProvider;
|
||||||
import docking.DialogComponentProvider;
|
import docking.DialogComponentProvider;
|
||||||
import docking.widgets.combobox.GhidraComboBox;
|
import docking.widgets.combobox.GhidraComboBox;
|
||||||
import docking.widgets.table.threaded.ThreadedTableModel;
|
import docking.widgets.table.threaded.ThreadedTableModel;
|
||||||
import ghidra.GhidraOptions;
|
|
||||||
import ghidra.app.plugin.core.searchtext.SearchTextPlugin;
|
import ghidra.app.plugin.core.searchtext.SearchTextPlugin;
|
||||||
import ghidra.app.plugin.core.string.StringTableProvider;
|
import ghidra.app.plugin.core.string.StringTableProvider;
|
||||||
import ghidra.app.plugin.core.table.TableComponentProvider;
|
import ghidra.app.plugin.core.table.TableComponentProvider;
|
||||||
|
import ghidra.app.util.SearchConstants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Captures screenshots associated with Memory Search.
|
* Captures screenshots associated with Memory Search.
|
||||||
|
@ -160,7 +160,7 @@ public class SearchScreenShots extends AbstractSearchScreenShots {
|
||||||
// custom program we've loaded. Also, we are NOT changing the option so that dialog
|
// custom program we've loaded. Also, we are NOT changing the option so that dialog
|
||||||
// that is shown will have the default value
|
// that is shown will have the default value
|
||||||
searchPlugin = env.getPlugin(SearchTextPlugin.class);
|
searchPlugin = env.getPlugin(SearchTextPlugin.class);
|
||||||
searchPlugin.optionsChanged(null, GhidraOptions.OPTION_SEARCH_LIMIT, null, 10);
|
searchPlugin.optionsChanged(null, SearchConstants.SEARCH_LIMIT_NAME, null, 10);
|
||||||
|
|
||||||
performAction("Search Text", "SearchTextPlugin", false);
|
performAction("Search Text", "SearchTextPlugin", false);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue