Merge remote-tracking branch 'origin/GP-6483_ryanmkurtz_options--SQUASHED'

This commit is contained in:
Ryan Kurtz
2026-04-03 13:03:26 -04:00
42 changed files with 1654 additions and 671 deletions
@@ -29,7 +29,6 @@ import org.jdom2.JDOMException;
import db.Transaction;
import ghidra.app.util.Option;
import ghidra.app.util.bin.ByteProvider;
import ghidra.app.util.importer.DomainFileOption;
import ghidra.app.util.importer.MessageLog;
import ghidra.framework.model.DomainFile;
import ghidra.framework.model.DomainObject;
@@ -232,8 +231,9 @@ public class TenetLoader implements Loader {
final DomainObject domainObject, final boolean loadIntoProgram,
final boolean mirrorFsLayout) {
final List<Option> list = new ArrayList<>();
list.add(new DomainFileOption(DOMAIN_FILE_OPTION_NAME,
COMMAND_LINE_ARG_PREFIX + "-associatedProgram", false));
list.add(Option.newDomainFile(DOMAIN_FILE_OPTION_NAME)
.commandLineArgument(createArg("-associatedProgram"))
.build());
return list;
}
@@ -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.
@@ -26,7 +26,7 @@ import ghidra.trace.model.Trace;
// TODO: perhaps getApplicableExporters should use domainObject's class, not file's object class.
// TODO: Where un-supported, be less abrasive, e.g., present empty managers.
public class TraceViewXmlExporter extends XmlExporter {
private final Map<String, Object> hideOpts = Map.of(
private final Map<String, Boolean> hideOpts = Map.of(
"Properties", false,
"Relocation Table", false,
"External Libraries", false);
@@ -48,8 +48,8 @@ public class TraceViewXmlExporter extends XmlExporter {
public void setOptions(List<Option> options) throws OptionException {
List<Option> opts = new ArrayList<>(options);
options.stream().filter(o -> !hideOpts.keySet().contains(o.getName())).forEach(opts::add);
for (Map.Entry<String, Object> ent : hideOpts.entrySet()) {
opts.add(new Option(ent.getKey(), ent.getValue()));
for (Map.Entry<String, Boolean> ent : hideOpts.entrySet()) {
opts.add(Option.newBoolean(ent.getKey()).value(ent.getValue()).build());
}
super.setOptions(opts);
}
@@ -0,0 +1,116 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util;
import ghidra.app.util.importer.options.AbstractOption;
/**
* A class to build {@link AbstractOption}s
*
* @param <ValueType> The option value type
* @param <OptionType> The build option type
*/
public abstract class AbstractOptionBuilder<ValueType, OptionType extends AbstractOption<ValueType>> {
protected String name;
protected String group;
protected ValueType value;
protected String commandLineArgument;
protected String description;
protected String stateKey;
protected boolean hidden;
/**
* Creates a new {@link AbstractOptionBuilder}
*
* @param name The name of the {@link Option} to be built
*/
public AbstractOptionBuilder(String name) {
this.name = name;
}
/**
* Sets the {@link Option}'s group
*
* @param g The {@link Option}'s group
* @return This {@link AbstractOptionBuilder}
*/
public AbstractOptionBuilder<ValueType, OptionType> group(String g) {
this.group = g;
return this;
}
/**
* Sets the {@link Option}'s value
*
* @param v The {@link Option}'s value
* @return This {@link AbstractOptionBuilder}
*/
public AbstractOptionBuilder<ValueType, OptionType> value(ValueType v) {
this.value = v;
return this;
}
/**
* Sets the {@link Option}'s command line argument
*
* @param arg The {@link Option}'s command line argument
* @return This {@link AbstractOptionBuilder}
*/
public AbstractOptionBuilder<ValueType, OptionType> commandLineArgument(String arg) {
this.commandLineArgument = arg;
return this;
}
/**
* Sets the {@link Option}'s description
*
* @param desc The {@link Option}'s description
* @return This {@link AbstractOptionBuilder}
*/
public AbstractOptionBuilder<ValueType, OptionType> description(String desc) {
this.description = desc;
return this;
}
/**
* Sets the {@link Option}'s state key
*
* @param key The {@link Option}'s state key
* @return This {@link AbstractOptionBuilder}
*/
public AbstractOptionBuilder<ValueType, OptionType> stateKey(String key) {
this.stateKey = key;
return this;
}
/**
* Sets whether or not the {@link Option} is hidden
*
* @param hide True if the {@link Option} should be hidden; otherwise, false
* @return This {@link AbstractOptionBuilder}
*/
public AbstractOptionBuilder<ValueType, OptionType> hidden(boolean hide) {
this.hidden = hide;
return this;
}
/**
* {@return a new {@link AbstractOption} based on the current state of this
* {@link AbstractOptionBuilder}}
*/
public abstract OptionType build();
}
@@ -17,99 +17,203 @@ package ghidra.app.util;
import java.awt.Component;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import ghidra.app.util.importer.options.*;
import ghidra.framework.main.AppInfo;
import ghidra.framework.model.Project;
import ghidra.framework.options.SaveState;
import ghidra.program.model.address.*;
import ghidra.util.NumericUtilities;
import ghidra.program.model.address.AddressFactory;
/**
* Container class to hold a name, value, and class of the value.
* Container class to hold an option
*/
public class Option {
/**
* {@return a new {@link ghidra.app.util.importer.options.BooleanOption.Builder}}
*
* @param name The name of the option
*/
public static BooleanOption.Builder newBoolean(String name) {
return new BooleanOption.Builder(name);
}
/**
* {@return a new {@link ghidra.app.util.importer.options.StringOption.Builder}}
*
* @param name The name of the option
*/
public static StringOption.Builder newString(String name) {
return new StringOption.Builder(name);
}
/**
* {@return a new {@link ghidra.app.util.importer.options.IntegerOption.Builder}}
*
* @param name The name of the option
*/
public static IntegerOption.Builder newInteger(String name) {
return new IntegerOption.Builder(name);
}
/**
* {@return a new {@link ghidra.app.util.importer.options.HexLongOption.Builder}}
*
* @param name The name of the option
*/
public static HexLongOption.Builder newHexLong(String name) {
return new HexLongOption.Builder(name);
}
/**
* {@return a new {@link ghidra.app.util.importer.options.AddressOption.Builder}}
*
* @param name The name of the option
*/
public static AddressOption.Builder newAddress(String name) {
return new AddressOption.Builder(name);
}
/**
* {@return a new {@link ghidra.app.util.importer.options.AddressSpaceOption.Builder}}
*
* @param name The name of the option
*/
public static AddressSpaceOption.Builder newAddressSpace(String name) {
return new AddressSpaceOption.Builder(name);
}
/**
* {@return a new {@link ghidra.app.util.importer.options.DomainFileOption.Builder}}
*
* @param name The name of the option
*/
public static DomainFileOption.Builder newDomainFile(String name) {
return new DomainFileOption.Builder(name);
}
/**
* {@return a new {@link ghidra.app.util.importer.options.DomainFolderOption.Builder}}
*
* @param name The name of the option
*/
public static DomainFolderOption.Builder newDomainFolder(String name) {
return new DomainFolderOption.Builder(name);
}
private final String group;
private final String name;
private final Class<?> valueClass;
private final String commandLineArgument;
private final String stateKey;
private final boolean hidden;
private final String description;
private Object value;
private OptionListener listener;
/**
* Construct a new Option.
* @param name name of the option
* @param value value of the option. Value can't be null with this constructor.
* @throws IllegalArgumentException if value is null
* Constructs a new {@link Option}
*
* @param name the name of the option
* @param value the value of the option
* @throws IllegalArgumentException if value is {@code null}
* @deprecated use {@link AbstractOptionBuilder} subclasses instead
*/
@Deprecated(since = "12.2", forRemoval = true)
public Option(String name, Object value) {
this(null, name, value);
}
/**
* Construct a new Option.
* @param group Name for group of options
* @param name name of the option
* @param value value of the option
* @throws IllegalArgumentException if value is null
* Constructs a new {@link Option}
*
* @param group the name for group of options
* @param name the name of the option
* @param value the value of the option
* @throws IllegalArgumentException if value is {@code null}
* @deprecated use {@link AbstractOptionBuilder} subclasses instead
*/
@Deprecated(since = "12.2", forRemoval = true)
public Option(String group, String name, Object value) {
this(name, getValueClass(value), value, null, group);
}
/**
* Construct a new Option.
* @param name name of the option
* @param valueClass class of the option's value
*
* Constructs a new {@link Option}
*
* @param name the name of the option
* @param valueClass valueClass the type of the option value
* @deprecated use {@link AbstractOptionBuilder} subclasses instead
*/
@Deprecated(since = "12.2", forRemoval = true)
public Option(String name, Class<?> valueClass) {
this(name, valueClass, null, null, null);
}
/**
* Construct a new Option
* @param name name of the option
* @param value value of the option
* @param valueClass class of the option's value
* @param arg the option's command line argument
*
* Constructs a new {@link Option}
*
* @param name the name of the option
* @param valueClass valueClass the type of the option value, which should match {@code <T>}
* @param value the value of the option (could be {@code null})
* @param arg the option's command line argument (could be {@code null})
* @deprecated use {@link AbstractOptionBuilder} subclasses instead
*/
@Deprecated(since = "12.2", forRemoval = true)
public Option(String name, Object value, Class<?> valueClass, String arg) {
this(name, valueClass, value, arg, null);
}
/**
* Construct a new Option
* Constructs a new {@link Option}
*
* @param name name of the option
* @param valueClass class of the option's value
* @param value value of the option
* @param arg the option's command line argument
* @param group Name for group of options
* @param name the name of the option
* @param valueClass valueClass the type of the option value, which should match {@code <T>}
* @param value the value of the option (could be {@code null})
* @param arg the option's command line argument (could be {@code null})
* @param group the name for group of options (could be {@code null})
* @deprecated use {@link AbstractOptionBuilder} subclasses instead
*/
@Deprecated(since = "12.2", forRemoval = true)
public Option(String name, Class<?> valueClass, Object value, String arg, String group) {
this(name, valueClass, value, arg, group, null, false);
}
/**
* Construct a new Option
* Constructs a new {@link Option}
*
* @param name name of the option
* @param valueClass class of the option's value
* @param value value of the option
* @param arg the option's command line argument
* @param group Name for group of options
* @param stateKey state key name
* @param name the name of the option
* @param valueClass valueClass the type of the option value, which should match {@code <T>}
* @param value the value of the option (could be {@code null})
* @param arg the option's command line argument (could be {@code null})
* @param group the name for group of options (could be {@code null})
* @param stateKey the state key name (could be {@code null})
* @param hidden true if this option should be hidden from the user; otherwise, false
* @deprecated use {@link AbstractOptionBuilder} subclasses instead
*/
@Deprecated(since = "12.2", forRemoval = true)
public Option(String name, Class<?> valueClass, Object value, String arg, String group,
String stateKey, boolean hidden) {
this(name, valueClass, value, arg, group, stateKey, hidden, null);
}
/**
* Constructs a new {@link Option}.
*
* @param name the name of the option
* @param valueClass valueClass the type of the option value, which should match {@code <T>}
* @param value the value of the option (could be {@code null})
* @param arg the option's command line argument (could be {@code null})
* @param group the name for group of options (could be {@code null})
* @param stateKey the state key name (could be {@code null})
* @param hidden true if this option should be hidden from the user; otherwise, false
* @param description a description of the option (could be {@code null})
*/
protected Option(String name, Class<?> valueClass, Object value, String arg, String group,
String stateKey, boolean hidden, String description) {
this.name = name;
this.valueClass = valueClass;
this.commandLineArgument = arg;
@@ -117,22 +221,28 @@ public class Option {
this.value = value;
this.stateKey = stateKey;
this.hidden = hidden;
this.description = description;
}
/**
* Sets this option's listener
*
* @param listener The {@link OptionListener} to set
*/
public void setOptionListener(OptionListener listener) {
this.listener = listener;
}
/**
* Override if you want to provide a custom widget for selecting your
* options.
* Override if you want to provide a custom widget for selecting your options.
* <p>
* Important! If you override this you MUST also override the {@link #copy()}
* method so it returns a new instance of your custom editor.
* Important! If you override this you MUST also override the {@link #copy()} method so it
* returns a new instance of your custom editor.
*
* @return the custom editor
* @param addressFactoryService The {@link AddressFactoryService}
* @return the custom editor {@link Component}, or {@code null} if there isn't one
*/
public Component getCustomEditorComponent() {
public Component getCustomEditorComponent(AddressFactoryService addressFactoryService) {
return null;
}
@@ -165,10 +275,13 @@ public class Option {
}
/**
* Set the value for this option.
* Set the value for this option
*
* @param object value of this option
* @throws IllegalArgumentException if the type of the object doesn't not match this option's
* value class
*/
public void setValue(Object object) {
public void setValue(Object object) throws IllegalArgumentException {
if (object != null && !valueClass.isAssignableFrom(object.getClass())) {
throw new IllegalArgumentException("Value class does not match! Expected " +
valueClass + ", but got " + object.getClass());
@@ -190,63 +303,8 @@ public class Option {
* @return True if the value was successfully parsed and set; otherwise, false.
*/
public boolean parseAndSetValueByType(String str, AddressFactory addressFactory) {
if (getValueClass() == null) {
return false;
}
if (Boolean.class.isAssignableFrom(getValueClass())) {
try {
setValue(BooleanUtils.toBoolean(str, "true", "false"));
}
catch (IllegalArgumentException e) {
return false;
}
}
else if (HexLong.class.isAssignableFrom(getValueClass())) {
try {
setValue(new HexLong(NumericUtilities.parseHexLong(str)));
}
catch (NumberFormatException e) {
return false;
}
}
else if (Integer.class.isAssignableFrom(getValueClass())) {
try {
setValue(Integer.decode(str));
}
catch (NumberFormatException e) {
return false;
}
}
else if (Address.class.isAssignableFrom(getValueClass())) {
try {
Address origAddr = (Address) getValue();
Address newAddr = null;
if (origAddr != null) {
newAddr = origAddr.getAddress(str);
}
else {
if (addressFactory == null) {
throw new RuntimeException("Attempted to use Address type option (" +
getName() + ") without specifying Address Factory");
}
newAddr = addressFactory.getDefaultAddressSpace().getAddress(str);
}
if (newAddr == null) {
return false;
}
setValue(newAddr);
}
catch (AddressFormatException e) {
return false;
}
}
else if (String.class.isAssignableFrom(getValueClass())) {
setValue(str);
}
else {
return false;
}
return true;
// Subclasses can override this if they need parsings support
return false;
}
/**
@@ -293,20 +351,38 @@ public class Option {
return hidden;
}
/**
* {@return the option's description (could be null)}
*/
public String getDescription() {
return description;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
/**
* Creates a copy of this Option object.
* @return a copy of this Option object.
* {@return a copy of this {@link Option} object}
* <p>
* NOTE: {@link Option} subclasses should always overwrite this method so they can return
* their exact type, instead of the more generic {@link Option} type.
* <p>
* NOTE: When the deprecated constructors of this class get removed, this method should become
* abstract.
*/
public Option copy() {
return new Option(name, valueClass, value, commandLineArgument, group, stateKey, hidden);
return new Option(name, valueClass, value, commandLineArgument, group, stateKey, hidden,
description);
}
private static Class<?> getValueClass(Object v) {
/**
* {@return the class type of the given value}
*
* @throws IllegalArgumentException if the given value is {@code null}
*/
private static Class<?> getValueClass(Object v) throws IllegalArgumentException {
if (v == null) {
throw new IllegalArgumentException("Value cannot be null without specifying class.");
}
@@ -21,17 +21,10 @@ import java.util.List;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.apache.commons.collections4.map.LazyMap;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.combobox.GComboBox;
import docking.widgets.label.GLabel;
import docking.widgets.textfield.IntegerTextField;
import ghidra.framework.options.SaveState;
import ghidra.program.model.address.*;
import ghidra.util.exception.AssertException;
import ghidra.util.layout.*;
@@ -193,195 +186,12 @@ public class OptionsEditorPanel extends JPanel {
* is not available).
*/
private Component getEditorComponent(Option option) {
Component customEditorComponent = option.getCustomEditorComponent();
if (customEditorComponent != null) {
return customEditorComponent;
}
Class<?> optionClass = option.getValueClass();
if (Address.class.isAssignableFrom(optionClass)) {
return getAddressEditorComponent(option);
}
else if (Boolean.class.isAssignableFrom(optionClass)) {
return getBooleanEditorComponent(option);
}
else if (Long.class.isAssignableFrom(optionClass)) {
return getLongEditorComponent(option);
}
else if (Integer.class.isAssignableFrom(optionClass)) {
return getIntegerEditorComponent(option);
}
else if (HexLong.class.isAssignableFrom(optionClass)) {
return getHexLongEditorComponent(option);
}
else if (String.class.isAssignableFrom(optionClass)) {
return getStringEditorComponent(option);
}
else if (AddressSpace.class.isAssignableFrom(optionClass)) {
return getAddressSpaceEditorComponent(option);
}
else {
Component customEditorComponent = option.getCustomEditorComponent(addressFactoryService);
if (customEditorComponent == null) {
throw new AssertException(
"Attempted to get default editor component for Option type: " +
optionClass.getName() + ". Please register a custom editor");
}
}
private Component getAddressSpaceEditorComponent(Option option) {
if (addressFactoryService == null) {
return null;
}
JComboBox<AddressSpace> combo = new GComboBox<>();
AddressFactory addressFactory = addressFactoryService.getAddressFactory();
AddressSpace[] spaces =
addressFactory == null ? new AddressSpace[0] : addressFactory.getAddressSpaces();
for (AddressSpace space : spaces) {
combo.addItem(space);
}
AddressSpace space = (AddressSpace) option.getValue();
if (space != null) {
combo.setSelectedItem(space);
}
combo.addActionListener(e -> {
// called whenever the combobox changes to push the value back to the Option that is
// our 'model'
option.setValue(combo.getSelectedItem());
});
return combo;
}
private Component getStringEditorComponent(Option option) {
final SaveState state = option.getState();
String defaultValue = (String) option.getValue();
String value =
state != null ? state.getString(option.getName(), defaultValue) : defaultValue;
option.setValue(value);
JTextField tf = new JTextField(5);
tf.setName(option.getName());
tf.getDocument().addDocumentListener(new ImporterDocumentListener(option, tf, state));
tf.setText(value);
return tf;
}
private Component getHexLongEditorComponent(Option option) {
final SaveState state = option.getState();
HexLong defaultValue = (HexLong) option.getValue();
long value = state != null ? state.getLong(option.getName(), defaultValue.longValue())
: defaultValue.longValue();
option.setValue(new HexLong(value));
IntegerTextField field = new IntegerTextField();
field.setValue(value);
field.setHexMode();
field.addChangeListener(e -> {
option.setValue(new HexLong(field.getLongValue()));
if (state != null) {
state.putLong(option.getName(), field.getLongValue());
}
});
return field.getComponent();
}
private Component getIntegerEditorComponent(Option option) {
final SaveState state = option.getState();
int defaultValue = (int) option.getValue();
int value = state != null ? state.getInt(option.getName(), defaultValue) : defaultValue;
option.setValue(value);
IntegerTextField field = new IntegerTextField();
field.setValue(value);
field.addChangeListener(e -> {
option.setValue(field.getIntValue());
if (state != null) {
state.putInt(option.getName(), field.getIntValue());
}
});
return field.getComponent();
}
private Component getLongEditorComponent(Option option) {
final SaveState state = option.getState();
long defaultValue = (long) option.getValue();
long value =
state != null ? state.getLong(option.getName(), defaultValue) : defaultValue;
option.setValue(value);
IntegerTextField field = new IntegerTextField();
field.setValue(value);
field.addChangeListener(e -> {
option.setValue(field.getLongValue());
if (state != null) {
state.putLong(option.getName(), field.getLongValue());
}
});
return field.getComponent();
}
private Component getBooleanEditorComponent(Option option) {
final SaveState state = option.getState();
boolean defaultValue = (boolean) option.getValue();
boolean initialState =
state != null ? state.getBoolean(option.getName(), defaultValue) : defaultValue;
option.setValue(initialState);
GCheckBox cb = new GCheckBox();
cb.setName(option.getName());
cb.setSelected(initialState);
cb.addItemListener(e -> {
option.setValue(cb.isSelected());
if (state != null) {
state.putBoolean(option.getName(), cb.isSelected());
}
});
return cb;
}
private Component getAddressEditorComponent(Option option) {
if (addressFactoryService == null) {
return null;
}
AddressFactory addressFactory = addressFactoryService.getAddressFactory();
AddressInput addressInput = new AddressInput(a -> option.setValue(a));
addressInput.setName(option.getName());
Address addr = (Address) option.getValue();
if (addr == null && addressFactory != null) {
addr = addressFactory.getDefaultAddressSpace().getAddress(0);
option.setValue(addr);
}
addressInput.setAddressFactory(addressFactory);
addressInput.setAddress(addr);
return addressInput;
}
}
class ImporterDocumentListener implements DocumentListener {
private Option option;
private JTextField textField;
private SaveState state;
ImporterDocumentListener(Option option, JTextField textField, SaveState state) {
this.option = option;
this.textField = textField;
this.state = state;
}
@Override
public void insertUpdate(DocumentEvent e) {
updated();
}
@Override
public void removeUpdate(DocumentEvent e) {
updated();
}
@Override
public void changedUpdate(DocumentEvent e) {
updated();
}
private void updated() {
String text = textField.getText();
option.setValue(text);
if (state != null) {
state.putString(option.getName(), text);
option.getValueClass().getName() + ". Please register a custom editor");
}
return customEditorComponent;
}
}
@@ -98,8 +98,9 @@ public class IntelHexExporter extends Exporter {
}
Program program = (Program) domainObject;
addressSpaceOption = new Option("Address Space",
program.getAddressFactory().getDefaultAddressSpace(), AddressSpace.class, null);
addressSpaceOption = Option.newAddressSpace("Address Space")
.value(program.getAddressFactory().getDefaultAddressSpace())
.build();
if (recordSizeOption == null) {
recordSizeOption = new RecordSizeOption("Record Size", Integer.class);
@@ -235,16 +236,16 @@ public class IntelHexExporter extends Exporter {
private final RecordSizeComponent comp = new RecordSizeComponent(DEFAULT_RECORD_SIZE);
public RecordSizeOption(String name, Class<?> valueClass) {
super(name, valueClass);
super(name, valueClass, null, null, null, null, false, null);
}
public RecordSizeOption(String name, Class<?> valueClass, Object value, String arg,
String group) {
super(name, valueClass, value, arg, group);
super(name, valueClass, value, arg, group, null, false, null);
}
@Override
public Component getCustomEditorComponent() {
public Component getCustomEditorComponent(AddressFactoryService addressFactoryService) {
return comp;
}
@@ -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.
@@ -220,10 +220,14 @@ public class OriginalFileExporter extends Exporter {
public List<Option> getOptions(DomainObjectService domainObjectService) {
if (options == null) {
options = new ArrayList<>();
options.add(new Option(USER_MODS_OPTION_NAME, USER_MODS_OPTION_DEFAULT));
options.add(Option.newBoolean(USER_MODS_OPTION_NAME)
.value(USER_MODS_OPTION_DEFAULT)
.build());
if (domainObjectService.getDomainObject() instanceof Program program &&
program.getMemory().getAllFileBytes().size() > 1) {
options.add(new Option(CREATE_DIR_OPTION_NAME, CREATE_DIR_OPTION_DEFAULT));
options.add(Option.newBoolean(CREATE_DIR_OPTION_NAME)
.value(CREATE_DIR_OPTION_DEFAULT)
.build());
}
}
return options;
@@ -15,7 +15,8 @@
*/
package ghidra.app.util.exporter;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import ghidra.app.util.Option;
import ghidra.app.util.OptionException;
@@ -105,42 +106,88 @@ class ProgramTextOptions {
}
List<Option> getOptions() {//TODO add right into list
Option[] options = new Option[] {
new Option(OPTION_INCLUDED_TYPES, OPTION_SHOW_COMMENTS, Boolean.valueOf(showComments)),
new Option(OPTION_INCLUDED_TYPES, OPTION_SHOW_PROPERTIES,
Boolean.valueOf(showProperties)),
new Option(OPTION_INCLUDED_TYPES, OPTION_SHOW_STRUCTURES,
Boolean.valueOf(showStructures)),
new Option(OPTION_INCLUDED_TYPES, OPTION_SHOW_UNDEFINED,
Boolean.valueOf(showUndefinedData)),
new Option(OPTION_INCLUDED_TYPES, OPTION_SHOW_REF_HEADER,
Boolean.valueOf(showReferenceHeaders)),
new Option(OPTION_INCLUDED_TYPES, OPTION_SHOW_BACK_REFS,
Boolean.valueOf(showBackReferences)),
new Option(OPTION_INCLUDED_TYPES, OPTION_SHOW_FORWARD_REFS,
Boolean.valueOf(showForwardReferences)),
new Option(OPTION_INCLUDED_TYPES, OPTION_SHOW_FUNCTIONS,
Boolean.valueOf(showFunctions)),
new Option(OPTION_INCLUDED_TYPES, OPTION_SHOW_BLOCK_NAMES,
Boolean.valueOf(showBlockNameInOperands)),
new Option(OPTION_FIELD_WIDTHS, OPTION_WIDTH_LABEL, Integer.valueOf(labelWidth)),
new Option(OPTION_FIELD_WIDTHS, OPTION_WIDTH_ADDR, Integer.valueOf(addrWidth)),
new Option(OPTION_FIELD_WIDTHS, OPTION_WIDTH_BYTES, Integer.valueOf(bytesWidth)),
new Option(OPTION_FIELD_WIDTHS, OPTION_WIDTH_PREMNEMONIC,
Integer.valueOf(preMnemonicWidth)),
new Option(OPTION_FIELD_WIDTHS, OPTION_WIDTH_MNEMONIC, Integer.valueOf(mnemonicWidth)),
new Option(OPTION_FIELD_WIDTHS, OPTION_WIDTH_OPERAND, Integer.valueOf(operandWidth)),
new Option(OPTION_FIELD_WIDTHS, OPTION_WIDTH_EOL, Integer.valueOf(eolWidth)),
new Option(OPTION_FIELD_WIDTHS, OPTION_WIDTH_REF, Integer.valueOf(refWidth)),
new Option(OPTION_FIELD_WIDTHS, OPTION_WIDTH_DATA_FIELD,
Integer.valueOf(dataFieldNameWidth)),
new Option(OPTION_PREFIXES, OPTION_ADV_LABEL_SUFFIX, labelSuffix),
new Option(OPTION_PREFIXES, OPTION_ADV_COMMENT_SUFFIX, commentPrefix), };
List<Option> optionsList = new ArrayList<Option>();
Collections.addAll(optionsList, options);
return optionsList;
List<Option> optionList = new ArrayList<>();
optionList.add(Option.newBoolean(OPTION_SHOW_COMMENTS)
.group(OPTION_INCLUDED_TYPES)
.value(showComments)
.build());
optionList.add(Option.newBoolean(OPTION_SHOW_PROPERTIES)
.group(OPTION_INCLUDED_TYPES)
.value(showProperties)
.build());
optionList.add(Option.newBoolean(OPTION_SHOW_STRUCTURES)
.group(OPTION_INCLUDED_TYPES)
.value(showStructures)
.build());
optionList.add(Option.newBoolean(OPTION_SHOW_UNDEFINED)
.group(OPTION_INCLUDED_TYPES)
.value(showUndefinedData)
.build());
optionList.add(Option.newBoolean(OPTION_SHOW_REF_HEADER)
.group(OPTION_INCLUDED_TYPES)
.value(showReferenceHeaders)
.build());
optionList.add(Option.newBoolean(OPTION_SHOW_BACK_REFS)
.group(OPTION_INCLUDED_TYPES)
.value(showBackReferences)
.build());
optionList.add(Option.newBoolean(OPTION_SHOW_FORWARD_REFS)
.group(OPTION_INCLUDED_TYPES)
.value(showForwardReferences)
.build());
optionList.add(Option.newBoolean(OPTION_SHOW_FUNCTIONS)
.group(OPTION_INCLUDED_TYPES)
.value(showFunctions)
.build());
optionList.add(Option.newBoolean(OPTION_SHOW_BLOCK_NAMES)
.group(OPTION_INCLUDED_TYPES)
.value(showBlockNameInOperands)
.build());
optionList.add(Option.newInteger(OPTION_WIDTH_LABEL)
.group(OPTION_FIELD_WIDTHS)
.value(labelWidth)
.build());
optionList.add(Option.newInteger(OPTION_WIDTH_ADDR)
.group(OPTION_FIELD_WIDTHS)
.value(addrWidth)
.build());
optionList.add(Option.newInteger(OPTION_WIDTH_BYTES)
.group(OPTION_FIELD_WIDTHS)
.value(bytesWidth)
.build());
optionList.add(Option.newInteger(OPTION_WIDTH_PREMNEMONIC)
.group(OPTION_FIELD_WIDTHS)
.value(preMnemonicWidth)
.build());
optionList.add(Option.newInteger(OPTION_WIDTH_MNEMONIC)
.group(OPTION_FIELD_WIDTHS)
.value(mnemonicWidth)
.build());
optionList.add(Option.newInteger(OPTION_WIDTH_OPERAND)
.group(OPTION_FIELD_WIDTHS)
.value(operandWidth)
.build());
optionList.add(Option.newInteger(OPTION_WIDTH_EOL)
.group(OPTION_FIELD_WIDTHS)
.value(eolWidth)
.build());
optionList.add(Option.newInteger(OPTION_WIDTH_REF)
.group(OPTION_FIELD_WIDTHS)
.value(refWidth)
.build());
optionList.add(Option.newInteger(OPTION_WIDTH_DATA_FIELD)
.group(OPTION_FIELD_WIDTHS)
.value(dataFieldNameWidth)
.build());
optionList.add(Option.newString(OPTION_ADV_LABEL_SUFFIX)
.group(OPTION_PREFIXES)
.value(labelSuffix)
.build());
optionList.add(Option.newString(OPTION_ADV_COMMENT_SUFFIX)
.group(OPTION_PREFIXES)
.value(commentPrefix)
.build());
return optionList;
}
void setOptions(List<Option> options) throws OptionException {
@@ -1,59 +0,0 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.importer;
import java.awt.Component;
import javax.swing.JButton;
import docking.DockingWindowManager;
import ghidra.app.util.Option;
import ghidra.app.util.opinion.LibraryPathsDialog;
/**
* A dummy {@link Option} used to render a button that will allow the user to edit the global
* list of library search paths
*/
public class LibrarySearchPathDummyOption extends Option {
/**
* Creates a new {@link LibrarySearchPathDummyOption}
*
* @param name The name of the option
*/
public LibrarySearchPathDummyOption(String name) {
super(name, null);
}
@Override
public Component getCustomEditorComponent() {
JButton button = new JButton("Edit Paths");
button.addActionListener(e -> {
DockingWindowManager.showDialog(null, new LibraryPathsDialog());
});
return button;
}
@Override
public Class<?> getValueClass() {
return Object.class;
}
@Override
public Option copy() {
return new LibrarySearchPathDummyOption(getName());
}
}
@@ -0,0 +1,65 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.importer.options;
import ghidra.app.util.Option;
/**
* An {@link Option} that is specific to a value type
*
* @param <T> The {@link Option} value type
*/
public abstract class AbstractOption<T> extends Option {
/**
* A typed value that must stay synchronized with the parent {@link Option}'s {@code value}.
* This allows clients to work with the proper value type instead of a generic {@link Object}.
*/
private T value;
/**
* Construct a new {@link AbstractOption}
*
* @param name the name of the option
* @param valueClass valueClass the type of the option value, which should match {@code <T>}
* @param value the value of the option (could be {@code null})
* @param arg the option's command line argument (could be {@code null})
* @param group the name for group of options (could be {@code null})
* @param stateKey the state key name (could be {@code null})
* @param hidden true if this option should be hidden from the user; otherwise, false
* @param description a description of the option (could be {@code null})
*/
AbstractOption(String name, Class<T> valueClass, T value, String arg, String group,
String stateKey, boolean hidden, String description) {
super(name, valueClass, value, arg, group, stateKey, hidden, description);
this.value = value;
}
@Override
public T getValue() {
return value;
}
@Override
@SuppressWarnings("unchecked")
public void setValue(Object v) throws IllegalArgumentException {
this.value = (T) v; // must do this first, since super.setValue() calls the change listener
super.setValue(v);
}
@Override
public abstract AbstractOption<T> copy();
}
@@ -0,0 +1,118 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.importer.options;
import java.awt.Component;
import ghidra.app.util.*;
import ghidra.app.util.opinion.Loader;
import ghidra.program.model.address.*;
/**
* An {@link Option} used to specify an {@link Address}
*/
public class AddressOption extends AbstractOption<Address> {
/**
* Creates a new {@link AddressOption}
*
* @param name the name of the option
* @param value the value of the option
* @param arg the option's command line argument
* @param group the name for group of options
* @param stateKey the state key name
* @param hidden true if this option should be hidden from the user; otherwise, false
* @param description a description of the option
*/
public AddressOption(String name, Address value, String arg, String group, String stateKey,
boolean hidden, String description) {
super(name, Address.class, value, arg, group, Loader.OPTIONS_PROJECT_SAVE_STATE_KEY,
hidden, description);
}
@Override
public boolean parseAndSetValueByType(String str, AddressFactory addressFactory) {
try {
Address origAddr = getValue();
Address newAddr = null;
if (origAddr != null) {
newAddr = origAddr.getAddress(str);
}
else {
if (addressFactory == null) {
throw new RuntimeException("Attempted to use Address type option (" +
getName() + ") without specifying Address Factory");
}
newAddr = addressFactory.getDefaultAddressSpace().getAddress(str);
}
if (newAddr == null) {
return false;
}
setValue(newAddr);
}
catch (AddressFormatException e) {
return false;
}
return true;
}
@Override
public Component getCustomEditorComponent(AddressFactoryService addressFactoryService) {
if (addressFactoryService == null) {
return null;
}
AddressFactory addressFactory = addressFactoryService.getAddressFactory();
AddressInput addressInput = new AddressInput(a -> setValue(a));
addressInput.setName(getName());
addressInput.setToolTipText(getDescription());
Address addr = getValue();
if (addr == null && addressFactory != null) {
addr = addressFactory.getDefaultAddressSpace().getAddress(0);
setValue(addr);
}
addressInput.setAddressFactory(addressFactory);
addressInput.setAddress(addr);
return addressInput;
}
@Override
public AddressOption copy() {
return new AddressOption(getName(), getValue(), getArg(), getGroup(), getStateKey(),
isHidden(), getDescription());
}
/**
* Builds a {@link AddressOption}
*/
public static class Builder extends AbstractOptionBuilder<Address, AddressOption> {
/**
* Creates a new {@link Builder}
*
* @param name The name of the {@link AddressOption} to be built
*/
public Builder(String name) {
super(name);
}
@Override
public AddressOption build() {
return new AddressOption(name, value, commandLineArgument, group, stateKey, hidden,
description);
}
}
}
@@ -0,0 +1,107 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.importer.options;
import java.awt.Component;
import javax.swing.JComboBox;
import docking.widgets.combobox.GComboBox;
import ghidra.app.util.*;
import ghidra.app.util.opinion.Loader;
import ghidra.program.model.address.AddressFactory;
import ghidra.program.model.address.AddressSpace;
/**
* An {@link Option} used to specify an {@link AddressSpace}
*/
public class AddressSpaceOption extends AbstractOption<AddressSpace> {
/**
* Creates a new {@link AddressSpaceOption}
*
* @param name the name of the option
* @param value the value of the option
* @param arg the option's command line argument
* @param group the name for group of options
* @param stateKey the state key name
* @param hidden true if this option should be hidden from the user; otherwise, false
* @param description a description of the option
*/
public AddressSpaceOption(String name, AddressSpace value, String arg, String group,
String stateKey, boolean hidden, String description) {
super(name, AddressSpace.class, value, arg, group,
Loader.OPTIONS_PROJECT_SAVE_STATE_KEY, hidden, description);
}
@Override
public boolean parseAndSetValueByType(String str, AddressFactory addressFactory) {
// Implementation has not yet been needed
return false;
}
@Override
public Component getCustomEditorComponent(AddressFactoryService addressFactoryService) {
if (addressFactoryService == null) {
return null;
}
JComboBox<AddressSpace> combo = new GComboBox<>();
AddressFactory addressFactory = addressFactoryService.getAddressFactory();
AddressSpace[] spaces =
addressFactory == null ? new AddressSpace[0] : addressFactory.getAddressSpaces();
for (AddressSpace space : spaces) {
combo.addItem(space);
}
AddressSpace space = getValue();
if (space != null) {
combo.setSelectedItem(space);
}
combo.addActionListener(e -> {
// called whenever the combobox changes to push the value back to the Option that is
// our 'model'
setValue(combo.getSelectedItem());
});
combo.setToolTipText(getDescription());
return combo;
}
@Override
public AddressSpaceOption copy() {
return new AddressSpaceOption(getName(), getValue(), getArg(), getGroup(),
getStateKey(), isHidden(), getDescription());
}
/**
* Builds an {@link AddressSpaceOption}
*/
public static class Builder extends AbstractOptionBuilder<AddressSpace, AddressSpaceOption> {
/**
* Creates a new {@link Builder}
*
* @param name The name of the {@link AddressSpaceOption} to be built
*/
public Builder(String name) {
super(name);
}
@Override
public AddressSpaceOption build() {
return new AddressSpaceOption(name, value, commandLineArgument, group, stateKey, hidden,
description);
}
}
}
@@ -0,0 +1,107 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.importer.options;
import java.awt.Component;
import org.apache.commons.lang3.BooleanUtils;
import docking.widgets.checkbox.GCheckBox;
import ghidra.app.util.*;
import ghidra.app.util.opinion.Loader;
import ghidra.framework.options.SaveState;
import ghidra.program.model.address.AddressFactory;
/**
* An {@link Option} used to specify a {@link Boolean}
*/
public class BooleanOption extends AbstractOption<Boolean> {
/**
* Creates a new {@link BooleanOption}
*
* @param name the name of the option
* @param value the value of the option
* @param arg the option's command line argument
* @param group the name for group of options
* @param stateKey the state key name
* @param hidden true if this option should be hidden from the user; otherwise, false
* @param description a description of the option
*/
public BooleanOption(String name, boolean value, String arg, String group, String stateKey,
boolean hidden, String description) {
super(name, Boolean.class, value, arg, group, Loader.OPTIONS_PROJECT_SAVE_STATE_KEY,
hidden, description);
}
@Override
public boolean parseAndSetValueByType(String str, AddressFactory addressFactory) {
try {
setValue(BooleanUtils.toBoolean(str, "true", "false"));
return true;
}
catch (IllegalArgumentException e) {
return false;
}
}
@Override
public Component getCustomEditorComponent(AddressFactoryService addressFactoryService) {
final SaveState state = getState();
boolean defaultValue = getValue();
boolean initialState =
state != null ? state.getBoolean(getName(), defaultValue) : defaultValue;
setValue(initialState);
GCheckBox cb = new GCheckBox();
cb.setName(getName());
cb.setToolTipText(getDescription());
cb.setSelected(initialState);
cb.addItemListener(e -> {
setValue(cb.isSelected());
if (state != null) {
state.putBoolean(getName(), cb.isSelected());
}
});
return cb;
}
@Override
public BooleanOption copy() {
return new BooleanOption(getName(), getValue(), getArg(), getGroup(), getStateKey(),
isHidden(), getDescription());
}
/**
* Builds a {@link BooleanOption}
*/
public static class Builder extends AbstractOptionBuilder<Boolean, BooleanOption> {
/**
* Creates a new {@link Builder}
*
* @param name The name of the {@link BooleanOption} to be built
*/
public Builder(String name) {
super(name);
}
@Override
public BooleanOption build() {
return new BooleanOption(name, value, commandLineArgument, group, stateKey, hidden,
description);
}
}
}
@@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.importer;
package ghidra.app.util.importer.options;
import static ghidra.framework.main.DataTreeDialogType.*;
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.Objects;
import javax.swing.*;
@@ -26,6 +27,7 @@ import org.apache.commons.io.FilenameUtils;
import docking.widgets.button.BrowseButton;
import docking.widgets.textfield.ElidingFilePathTextField;
import ghidra.app.util.AddressFactoryService;
import ghidra.app.util.Option;
import ghidra.app.util.opinion.Loader;
import ghidra.framework.main.AppInfo;
@@ -36,23 +38,29 @@ import ghidra.framework.options.SaveState;
/**
* An {@link Option} used to specify a {@link DomainFile}
*/
public class DomainFileOption extends Option {
public class DomainFileOption extends StringOption {
/**
* Creates a new {@link DomainFileOption}
*
* @param name The name of the option
* @param arg The option's command line argument (could be null)
* @param hidden true if this option should be hidden from the user; otherwise, false
* @param name the name of the option
* @param value the value of the option
* @param arg the option's command line argument
* @param group the name for group of options
* @param stateKey the state key name
* @param hidden true if this option should be hidden from the user; otherwise, false
* @param description a description of the option
*/
public DomainFileOption(String name, String arg, boolean hidden) {
super(name, String.class, "", arg, null, Loader.OPTIONS_PROJECT_SAVE_STATE_KEY, hidden);
public DomainFileOption(String name, String value, String arg, String group,
String stateKey, boolean hidden, String description) {
super(name, value, arg, group, Loader.OPTIONS_PROJECT_SAVE_STATE_KEY,
hidden, description);
}
@Override
public Component getCustomEditorComponent() {
public Component getCustomEditorComponent(AddressFactoryService addressFactoryService) {
final SaveState state = getState();
String defaultValue = (String) getValue();
String defaultValue = getValue();
String lastFilePath =
state != null ? state.getString(getName(), defaultValue) : defaultValue;
setValue(lastFilePath);
@@ -63,7 +71,8 @@ public class DomainFileOption extends Option {
button.addActionListener(e -> {
DataTreeDialog dataTreeDialog =
new DataTreeDialog(null, "Choose a project file", OPEN);
String folderPath = lastFilePath.isBlank() ? "/" : FilenameUtils.getPath(lastFilePath);
String folderPath =
lastFilePath.isBlank() ? "/" : FilenameUtils.getPath(lastFilePath);
dataTreeDialog.setSelectedFolder(
AppInfo.getActiveProject().getProjectData().getFolder(folderPath));
dataTreeDialog.showComponent();
@@ -84,12 +93,29 @@ public class DomainFileOption extends Option {
}
@Override
public Class<?> getValueClass() {
return String.class;
public DomainFileOption copy() {
return new DomainFileOption(getName(), getValue(), getArg(), getGroup(), getStateKey(),
isHidden(), getDescription());
}
@Override
public Option copy() {
return new DomainFileOption(getName(), getArg(), isHidden());
/**
* Builds a {@link DomainFileOption}
*/
public static class Builder extends StringOption.Builder {
/**
* Creates a new {@link Builder}
*
* @param name The name of the {@link DomainFileOption} to be built
*/
public Builder(String name) {
super(name);
}
@Override
public DomainFileOption build() {
return new DomainFileOption(name, Objects.requireNonNullElse(value, ""),
commandLineArgument, group, stateKey, hidden, description);
}
}
}
@@ -13,17 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.importer;
package ghidra.app.util.importer.options;
import static ghidra.framework.main.DataTreeDialogType.*;
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.Objects;
import javax.swing.*;
import docking.widgets.button.BrowseButton;
import docking.widgets.textfield.ElidingFilePathTextField;
import ghidra.app.util.AddressFactoryService;
import ghidra.app.util.Option;
import ghidra.app.util.opinion.Loader;
import ghidra.framework.main.AppInfo;
@@ -34,23 +36,29 @@ import ghidra.framework.options.SaveState;
/**
* An {@link Option} used to specify a {@link DomainFolder}
*/
public class DomainFolderOption extends Option {
public class DomainFolderOption extends StringOption {
/**
* Creates a new {@link DomainFolderOption}
*
* @param name The name of the option
* @param arg The option's command line argument (could be null)
* @param hidden true if this option should be hidden from the user; otherwise, false
* @param name the name of the option
* @param value the value of the option
* @param arg the option's command line argument
* @param group the name for group of options
* @param stateKey the state key name
* @param hidden true if this option should be hidden from the user; otherwise, false
* @param description a description of the option
*/
public DomainFolderOption(String name, String arg, boolean hidden) {
super(name, String.class, "", arg, null, Loader.OPTIONS_PROJECT_SAVE_STATE_KEY, hidden);
public DomainFolderOption(String name, String value, String arg, String group,
String stateKey, boolean hidden, String description) {
super(name, value, arg, group, Loader.OPTIONS_PROJECT_SAVE_STATE_KEY, hidden,
description);
}
@Override
public Component getCustomEditorComponent() {
public Component getCustomEditorComponent(AddressFactoryService addressFactoryService) {
final SaveState state = getState();
String defaultValue = (String) getValue();
String defaultValue = getValue();
String lastFolderPath =
state != null ? state.getString(getName(), defaultValue) : defaultValue;
setValue(lastFolderPath);
@@ -82,12 +90,29 @@ public class DomainFolderOption extends Option {
}
@Override
public Class<?> getValueClass() {
return String.class;
public DomainFolderOption copy() {
return new DomainFolderOption(getName(), getValue(), getArg(), getGroup(),
getStateKey(), isHidden(), getDescription());
}
@Override
public Option copy() {
return new DomainFolderOption(getName(), getArg(), isHidden());
/**
* Builds a {@link DomainFolderOption}
*/
public static class Builder extends StringOption.Builder {
/**
* Creates a new {@link Builder}
*
* @param name The name of the {@link DomainFolderOption} to be built
*/
public Builder(String name) {
super(name);
}
@Override
public DomainFolderOption build() {
return new DomainFolderOption(name, Objects.requireNonNullElse(value, ""),
commandLineArgument, group, stateKey, hidden, description);
}
}
}
@@ -0,0 +1,106 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.importer.options;
import java.awt.Component;
import docking.widgets.textfield.IntegerTextField;
import ghidra.app.util.*;
import ghidra.app.util.opinion.Loader;
import ghidra.framework.options.SaveState;
import ghidra.program.model.address.AddressFactory;
import ghidra.util.NumericUtilities;
/**
* An {@link Option} used to specify a {@link HexLong}
*/
public class HexLongOption extends AbstractOption<HexLong> {
/**
* Creates a new {@link HexLongOption}
*
* @param name the name of the option
* @param value the value of the option
* @param arg the option's command line argument
* @param group the name for group of options
* @param stateKey the state key name
* @param hidden true if this option should be hidden from the user; otherwise, false
* @param description a description of the option
*/
public HexLongOption(String name, HexLong value, String arg, String group, String stateKey,
boolean hidden, String description) {
super(name, HexLong.class, value, arg, group, Loader.OPTIONS_PROJECT_SAVE_STATE_KEY,
hidden, description);
}
@Override
public boolean parseAndSetValueByType(String str, AddressFactory addressFactory) {
try {
setValue(new HexLong(NumericUtilities.parseHexLong(str)));
return true;
}
catch (NumberFormatException e) {
return false;
}
}
@Override
public Component getCustomEditorComponent(AddressFactoryService addressFactoryService) {
final SaveState state = getState();
HexLong defaultValue = getValue();
long initialState = state != null ? state.getLong(getName(), defaultValue.longValue())
: defaultValue.longValue();
setValue(new HexLong(initialState));
IntegerTextField field = new IntegerTextField();
field.setValue(initialState);
field.setHexMode();
field.getComponent().setToolTipText(getDescription());
field.addChangeListener(e -> {
setValue(new HexLong(field.getLongValue()));
if (state != null) {
state.putLong(getName(), field.getLongValue());
}
});
return field.getComponent();
}
@Override
public HexLongOption copy() {
return new HexLongOption(getName(), getValue(), getArg(), getGroup(), getStateKey(),
isHidden(), getDescription());
}
/**
* Builds a {@link HexLongOption}
*/
public static class Builder extends AbstractOptionBuilder<HexLong, HexLongOption> {
/**
* Creates a new {@link Builder}
*
* @param name The name of the {@link HexLongOption} to be built
*/
public Builder(String name) {
super(name);
}
@Override
public HexLongOption build() {
return new HexLongOption(name, value, commandLineArgument, group, stateKey, hidden,
description);
}
}
}
@@ -0,0 +1,103 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.importer.options;
import java.awt.Component;
import docking.widgets.textfield.IntegerTextField;
import ghidra.app.util.*;
import ghidra.app.util.opinion.Loader;
import ghidra.framework.options.SaveState;
import ghidra.program.model.address.AddressFactory;
/**
* An {@link Option} used to specify an {@link Integer}
*/
public class IntegerOption extends AbstractOption<Integer> {
/**
* Creates a new {@link IntegerOption}
*
* @param name the name of the option
* @param value the value of the option
* @param arg the option's command line argument
* @param group the name for group of options
* @param stateKey the state key name
* @param hidden true if this option should be hidden from the user; otherwise, false
* @param description a description of the option
*/
public IntegerOption(String name, int value, String arg, String group, String stateKey,
boolean hidden, String description) {
super(name, Integer.class, value, arg, group, Loader.OPTIONS_PROJECT_SAVE_STATE_KEY,
hidden, description);
}
@Override
public boolean parseAndSetValueByType(String str, AddressFactory addressFactory) {
try {
setValue(Integer.decode(str));
return true;
}
catch (NumberFormatException e) {
return false;
}
}
@Override
public Component getCustomEditorComponent(AddressFactoryService addressFactoryService) {
final SaveState state = getState();
int defaultValue = getValue();
int initialState = state != null ? state.getInt(getName(), defaultValue) : defaultValue;
setValue(initialState);
IntegerTextField field = new IntegerTextField();
field.setValue(initialState);
field.getComponent().setToolTipText(getDescription());
field.addChangeListener(e -> {
setValue(field.getIntValue());
if (state != null) {
state.putInt(getName(), field.getIntValue());
}
});
return field.getComponent();
}
@Override
public IntegerOption copy() {
return new IntegerOption(getName(), getValue(), getArg(), getGroup(), getStateKey(),
isHidden(), getDescription());
}
/**
* Builds a {@link IntegerOption}
*/
public static class Builder extends AbstractOptionBuilder<Integer, IntegerOption> {
/**
* Creates a new {@link Builder}
*
* @param name The name of the {@link IntegerOption} to be built
*/
public Builder(String name) {
super(name);
}
@Override
public IntegerOption build() {
return new IntegerOption(name, value, commandLineArgument, group, stateKey, hidden,
description);
}
}
}
@@ -0,0 +1,124 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.importer.options;
import java.awt.Component;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import ghidra.app.util.*;
import ghidra.app.util.opinion.Loader;
import ghidra.framework.options.SaveState;
import ghidra.program.model.address.AddressFactory;
/**
* An {@link Option} used to specify a {@link String}
*/
public class StringOption extends AbstractOption<String> {
/**
* Creates a new {@link IntegerOption}
*
* @param name the name of the option
* @param value the value of the option
* @param arg the option's command line argument
* @param group the name for group of options
* @param stateKey the state key name
* @param hidden true if this option should be hidden from the user; otherwise, false
* @param description a description of the option
*/
public StringOption(String name, String value, String arg, String group, String stateKey,
boolean hidden, String description) {
super(name, String.class, value, arg, group, Loader.OPTIONS_PROJECT_SAVE_STATE_KEY,
hidden, description);
}
@Override
public boolean parseAndSetValueByType(String str, AddressFactory addressFactory) {
setValue(str);
return true;
}
@Override
public Component getCustomEditorComponent(AddressFactoryService addressFactoryService) {
final SaveState state = getState();
String defaultValue = getValue();
String initialState =
state != null ? state.getString(getName(), defaultValue) : defaultValue;
setValue(initialState);
JTextField tf = new JTextField(5);
tf.setName(getName());
tf.setToolTipText(getDescription());
final StringOption thisOption = this;
tf.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
updated();
}
@Override
public void removeUpdate(DocumentEvent e) {
updated();
}
@Override
public void changedUpdate(DocumentEvent e) {
updated();
}
private void updated() {
String text = tf.getText();
thisOption.setValue(text);
if (state != null) {
state.putString(thisOption.getName(), text);
}
}
});
tf.setText(getValue());
return tf;
}
@Override
public StringOption copy() {
return new StringOption(getName(), getValue(), getArg(), getGroup(), getStateKey(),
isHidden(), getDescription());
}
/**
* Builds a {@link StringOption}
*/
public static class Builder extends AbstractOptionBuilder<String, StringOption> {
/**
* Creates a new {@link Builder}
*
* @param name The name of the {@link StringOption} to be built
*/
public Builder(String name) {
super(name);
}
@Override
public StringOption build() {
return new StringOption(name, value, commandLineArgument, group, stateKey, hidden,
description);
}
}
}
@@ -15,18 +15,22 @@
*/
package ghidra.app.util.opinion;
import java.awt.Component;
import java.io.IOException;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.swing.JButton;
import org.apache.commons.io.FilenameUtils;
import ghidra.app.util.Option;
import ghidra.app.util.OptionUtils;
import docking.DockingWindowManager;
import ghidra.app.util.*;
import ghidra.app.util.bin.ByteProvider;
import ghidra.app.util.importer.*;
import ghidra.app.util.importer.LibrarySearchPathManager;
import ghidra.app.util.importer.MessageLog;
import ghidra.formats.gfilesystem.*;
import ghidra.framework.model.*;
import ghidra.plugin.importer.ImporterPlugin;
@@ -282,22 +286,37 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
List<Option> list = super.getDefaultOptions(provider, loadSpec, domainObject,
loadIntoProgram, mirrorFsLayout);
list.add(new Option(LINK_EXISTING_OPTION_NAME, LINK_EXISTING_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-linkExistingProjectLibraries"));
list.add(new DomainFolderOption(LINK_SEARCH_FOLDER_OPTION_NAME,
Loader.COMMAND_LINE_ARG_PREFIX + "-projectLibrarySearchFolder", mirrorFsLayout));
list.add(new Option(LOAD_LIBRARY_OPTION_NAME, LOAD_LIBRARY_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-loadLibraries"));
list.add(Option.newBoolean(LINK_EXISTING_OPTION_NAME)
.value(LINK_EXISTING_OPTION_DEFAULT)
.commandLineArgument(createArg("-linkExistingProjectLibraries"))
.build());
list.add(Option.newDomainFolder(LINK_SEARCH_FOLDER_OPTION_NAME)
.commandLineArgument(createArg("-projectLibrarySearchFolder"))
.hidden(mirrorFsLayout)
.build());
list.add(Option.newBoolean(LOAD_LIBRARY_OPTION_NAME)
.value(LOAD_LIBRARY_OPTION_DEFAULT)
.commandLineArgument(createArg("-loadLibraries"))
.build());
list.add(new LibrarySearchPathDummyOption(LIBRARY_SEARCH_PATH_DUMMY_OPTION_NAME));
list.add(new Option(DEPTH_OPTION_NAME, DEPTH_OPTION_DEFAULT, Integer.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-libraryLoadDepth"));
list.add(new DomainFolderOption(LIBRARY_DEST_FOLDER_OPTION_NAME,
Loader.COMMAND_LINE_ARG_PREFIX + "-libraryDestinationFolder", mirrorFsLayout));
list.add(new Option(MIRROR_LAYOUT_OPTION_NAME, Boolean.class, mirrorFsLayout,
Loader.COMMAND_LINE_ARG_PREFIX + "-libraryMirrorLayout", null, null, mirrorFsLayout));
list.add(new Option(LOAD_ONLY_LIBRARIES_OPTION_NAME, Boolean.class,
LOAD_ONLY_LIBRARIES_OPTION_DEFAULT,
Loader.COMMAND_LINE_ARG_PREFIX + "-loadOnlyLibraries", null, null, true));
list.add(Option.newInteger(DEPTH_OPTION_NAME)
.value(DEPTH_OPTION_DEFAULT)
.commandLineArgument(createArg("-libraryLoadDepth"))
.build());
list.add(Option.newDomainFolder(LIBRARY_DEST_FOLDER_OPTION_NAME)
.commandLineArgument(createArg("-libraryDestinationFolder"))
.hidden(mirrorFsLayout)
.build());
list.add(Option.newBoolean(MIRROR_LAYOUT_OPTION_NAME)
.value(mirrorFsLayout)
.commandLineArgument(createArg("-libraryMirrorLayout"))
.hidden(mirrorFsLayout)
.build());
list.add(Option.newBoolean(LOAD_ONLY_LIBRARIES_OPTION_NAME)
.value(LOAD_ONLY_LIBRARIES_OPTION_DEFAULT)
.commandLineArgument(createArg("-loadOnlyLibraries"))
.hidden(true)
.build());
return list;
}
@@ -1168,4 +1187,40 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
private boolean isAbsoluteLibraryPath(String path) {
return FilenameUtils.getPrefixLength(path) > 0;
}
/**
* A dummy {@link Option} used to render a button that will allow the user to edit the global
* list of library search paths
*/
private static class LibrarySearchPathDummyOption extends Option {
/**
* Creates a new {@link LibrarySearchPathDummyOption}
*
* @param name The name of the option
*/
public LibrarySearchPathDummyOption(String name) {
super(name, null, null, null, null, null, false, null);
}
@Override
public Component getCustomEditorComponent(AddressFactoryService addressFactoryService) {
JButton button = new JButton("Edit Paths");
button.addActionListener(e -> {
DockingWindowManager.showDialog(null, new LibraryPathsDialog());
});
return button;
}
@Override
public Class<?> getValueClass() {
return Object.class;
}
@Override
public Option copy() {
return new LibrarySearchPathDummyOption(getName());
}
}
}
@@ -48,8 +48,10 @@ public abstract class AbstractOrdinalSupportLoader extends AbstractLibrarySuppor
DomainObject domainObject, boolean loadIntoProgram, boolean mirrorFsLayout) {
List<Option> list = super.getDefaultOptions(provider, loadSpec, domainObject,
loadIntoProgram, mirrorFsLayout);
list.add(new Option(ORDINAL_LOOKUP_OPTION_NAME, ORDINAL_LOOKUP_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-ordinalLookup"));
list.add(Option.newBoolean(ORDINAL_LOOKUP_OPTION_NAME)
.value(ORDINAL_LOOKUP_OPTION_DEFAULT)
.commandLineArgument(createArg("-ordinalLookup"))
.build());
return list;
}
@@ -54,8 +54,10 @@ abstract class AbstractPeDebugLoader extends AbstractOrdinalSupportLoader {
DomainObject domainObject, boolean loadIntoProgram, boolean mirrorFsLayout) {
List<Option> list = super.getDefaultOptions(provider, loadSpec, domainObject,
loadIntoProgram, mirrorFsLayout);
list.add(new Option(SHOW_LINE_NUMBERS_OPTION_NAME, SHOW_LINE_NUMBERS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-showDebugLineNumbers"));
list.add(Option.newBoolean(SHOW_LINE_NUMBERS_OPTION_NAME)
.value(SHOW_LINE_NUMBERS_OPTION_DEFAULT)
.commandLineArgument(createArg("-showDebugLineNumbers"))
.build());
return list;
}
@@ -162,10 +162,14 @@ public abstract class AbstractProgramLoader implements Loader {
public List<Option> getDefaultOptions(ByteProvider provider, LoadSpec loadSpec,
DomainObject domainObject, boolean loadIntoProgram, boolean mirrorFsLayout) {
ArrayList<Option> list = new ArrayList<>();
list.add(new Option(APPLY_LABELS_OPTION_NAME, shouldApplyProcessorLabelsByDefault(),
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-applyLabels"));
list.add(new Option(ANCHOR_LABELS_OPTION_NAME, true, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-anchorLabels"));
list.add(Option.newBoolean(APPLY_LABELS_OPTION_NAME)
.value(shouldApplyProcessorLabelsByDefault())
.commandLineArgument(createArg("-applyLabels"))
.build());
list.add(Option.newBoolean(ANCHOR_LABELS_OPTION_NAME)
.value(true)
.commandLineArgument("-anchorLabels")
.build());
return list;
}
@@ -369,19 +369,29 @@ public class BinaryLoader extends AbstractProgramLoader {
List<Option> list = new ArrayList<Option>();
if (loadIntoProgram) {
list.add(new Option(OPTION_NAME_IS_OVERLAY, isOverlay));
list.add(Option.newBoolean(OPTION_NAME_IS_OVERLAY)
.value(isOverlay)
.build());
}
else {
isOverlay = false;
}
list.add(new Option(OPTION_NAME_BLOCK_NAME, blockName, String.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-blockName"));
list.add(new Option(OPTION_NAME_BASE_ADDR, baseAddr, Address.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-baseAddr"));
list.add(new Option(OPTION_NAME_FILE_OFFSET, new HexLong(fileOffset), HexLong.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-fileOffset"));
list.add(new Option(OPTION_NAME_LEN, new HexLong(length), HexLong.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-length"));
list.add(Option.newString(OPTION_NAME_BLOCK_NAME)
.value(blockName)
.commandLineArgument(createArg("-blockName"))
.build());
list.add(Option.newAddress(OPTION_NAME_BASE_ADDR)
.value(baseAddr)
.commandLineArgument(createArg("-baseAddr"))
.build());
list.add(Option.newHexLong(OPTION_NAME_FILE_OFFSET)
.value(new HexLong(fileOffset))
.commandLineArgument(createArg("-fileOffset"))
.build());
list.add(Option.newHexLong(OPTION_NAME_LEN)
.value(new HexLong(length))
.commandLineArgument(createArg("-length"))
.build());
list.addAll(super.getDefaultOptions(provider, loadSpec, domainObject, loadIntoProgram,
mirrorFsLayout));
@@ -127,7 +127,9 @@ public class CoffLoader extends AbstractLibrarySupportLoader {
List<Option> list = super.getDefaultOptions(provider, loadSpec, domainObject,
loadIntoProgram, mirrorFsLayout);
if (!loadIntoProgram) {
list.add(new Option(FAKE_LINK_OPTION_NAME, FAKE_LINK_OPTION_DEFAULT));
list.add(Option.newBoolean(FAKE_LINK_OPTION_NAME)
.value(FAKE_LINK_OPTION_DEFAULT)
.build());
}
return list;
}
@@ -148,36 +148,46 @@ public class DyldCacheLoader extends AbstractProgramWrapperLoader {
List<Option> list = super.getDefaultOptions(provider, loadSpec, domainObject,
loadIntoProgram, mirrorFsLayout);
if (!loadIntoProgram) {
list.add(new Option(FIXUP_SLIDE_POINTERS_OPTION_NAME,
FIXUP_SLIDE_POINTERS_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-fixupSlidePointers"));
list.add(
new Option(MARKUP_SLIDE_POINTERS_OPTION_NAME, MARKUP_SLIDE_POINTERS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-markupSlidePointers"));
list.add(new Option(ADD_SLIDE_POINTER_RELOCATIONS_OPTION_NAME,
ADD_SLIDE_POINTERS_RELOCATIONS_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-addSlidePointerRelocations"));
list.add(
new Option(PROCESS_LOCAL_SYMBOLS_OPTION_NAME, PROCESS_LOCAL_SYMBOLS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processLocalSymbols"));
list.add(
new Option(MARKUP_LOCAL_SYMBOLS_OPTION_NAME, MARKUP_LOCAL_SYMBOLS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-markupLocalSymbols"));
list.add(
new Option(PROCESS_DYLIB_MEMORY_OPTION_NAME, PROCESS_DYLIB_MEMORY_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processDylibMemory"));
list.add(
new Option(PROCESS_DYLIB_SYMBOLS_OPTION_NAME, PROCESS_DYLIB_SYMBOLS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processDylibSymbols"));
list.add(
new Option(PROCESS_DYLIB_EXPORTS_OPTION_NAME, PROCESS_DYLIB_EXPORTS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processDylibExports"));
list.add(new Option(MARKUP_DYLIB_LC_DATA_OPTION_NAME,
MARKUP_DYLIB_LC_DATA_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-markupDylibLoadCommandData"));
list.add(
new Option(PROCESS_DYLIB_LIBOBJC_OPTION_NAME, PROCESS_DYLIB_LIBOBJC_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processLibobjc"));
list.add(Option.newBoolean(FIXUP_SLIDE_POINTERS_OPTION_NAME)
.value(FIXUP_SLIDE_POINTERS_OPTION_DEFAULT)
.commandLineArgument(createArg("-fixupSlidePointers"))
.build());
list.add(Option.newBoolean(MARKUP_SLIDE_POINTERS_OPTION_NAME)
.value(MARKUP_SLIDE_POINTERS_OPTION_DEFAULT)
.commandLineArgument(createArg("-markupSlidePointers"))
.build());
list.add(Option.newBoolean(ADD_SLIDE_POINTER_RELOCATIONS_OPTION_NAME)
.value(ADD_SLIDE_POINTERS_RELOCATIONS_OPTION_DEFAULT)
.commandLineArgument(createArg("-addSlidePointerRelocations"))
.build());
list.add(Option.newBoolean(PROCESS_LOCAL_SYMBOLS_OPTION_NAME)
.value(PROCESS_LOCAL_SYMBOLS_OPTION_DEFAULT)
.commandLineArgument(createArg("-processLocalSymbols"))
.build());
list.add(Option.newBoolean(MARKUP_LOCAL_SYMBOLS_OPTION_NAME)
.value(MARKUP_LOCAL_SYMBOLS_OPTION_DEFAULT)
.commandLineArgument(createArg("-markupLocalSymbols"))
.build());
list.add(Option.newBoolean(PROCESS_DYLIB_MEMORY_OPTION_NAME)
.value(PROCESS_DYLIB_MEMORY_OPTION_DEFAULT)
.commandLineArgument(createArg("-processDylibMemory"))
.build());
list.add(Option.newBoolean(PROCESS_DYLIB_SYMBOLS_OPTION_NAME)
.value(PROCESS_DYLIB_SYMBOLS_OPTION_DEFAULT)
.commandLineArgument(createArg("-processDylibSymbols"))
.build());
list.add(Option.newBoolean(PROCESS_DYLIB_EXPORTS_OPTION_NAME)
.value(PROCESS_DYLIB_EXPORTS_OPTION_DEFAULT)
.commandLineArgument(createArg("-processDylibExports"))
.build());
list.add(Option.newBoolean(MARKUP_DYLIB_LC_DATA_OPTION_NAME)
.value(MARKUP_DYLIB_LC_DATA_OPTION_DEFAULT)
.commandLineArgument(createArg("-markupDylibLoadCommandData"))
.build());
list.add(Option.newBoolean(PROCESS_DYLIB_LIBOBJC_OPTION_NAME)
.value(PROCESS_DYLIB_LIBOBJC_OPTION_DEFAULT)
.commandLineArgument(createArg("-processLibobjc"))
.build());
}
return list;
}
@@ -67,12 +67,15 @@ public class ElfLoaderOptionsFactory {
// NOTE: add-to-program is not supported
options.add(new Option(PERFORM_RELOCATIONS_NAME, PERFORM_RELOCATIONS_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-applyRelocations"));
options.add(Option.newBoolean(PERFORM_RELOCATIONS_NAME)
.value(PERFORM_RELOCATIONS_DEFAULT)
.commandLineArgument(Loader.COMMAND_LINE_ARG_PREFIX + "-applyRelocations")
.build());
options.add(
new Option(APPLY_UNDEFINED_SYMBOL_DATA_NAME, APPLY_UNDEFINED_SYMBOL_DATA_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-applyUndefinedData"));
options.add(Option.newBoolean(APPLY_UNDEFINED_SYMBOL_DATA_NAME)
.value(APPLY_UNDEFINED_SYMBOL_DATA_DEFAULT)
.commandLineArgument(Loader.COMMAND_LINE_ARG_PREFIX + "-applyUndefinedData")
.build());
ElfHeader elf = new ElfHeader(provider, null);
ElfLoadAdapter extensionAdapter = ElfExtensionFactory.getLoadAdapter(elf);
@@ -92,23 +95,30 @@ public class ElfLoaderOptionsFactory {
AddressSpace defaultSpace = language.getDefaultSpace();
String hexValueStr = getBaseAddressOffsetString(imageBase, defaultSpace);
options.add(new Option(IMAGE_BASE_OPTION_NAME, hexValueStr, String.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-imagebase"));
options.add(Option.newString(IMAGE_BASE_OPTION_NAME)
.value(hexValueStr)
.commandLineArgument(Loader.COMMAND_LINE_ARG_PREFIX + "-imagebase")
.build());
if (includeDataImageBaseOption(elf, language)) {
long minDataImageBase = getRecommendedMinimumDataImageBase(elf, language);
hexValueStr =
getBaseAddressOffsetString(minDataImageBase, language.getDefaultDataSpace());
options.add(new Option(IMAGE_DATA_IMAGE_BASE_OPTION_NAME, hexValueStr, String.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-dataImageBase"));
options.add(Option.newString(IMAGE_DATA_IMAGE_BASE_OPTION_NAME)
.value(hexValueStr)
.commandLineArgument(Loader.COMMAND_LINE_ARG_PREFIX + "-dataImageBase")
.build());
}
options.add(new Option(INCLUDE_OTHER_BLOCKS, INCLUDE_OTHER_BLOCKS_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-includeOtherBlocks"));
options.add(Option.newBoolean(INCLUDE_OTHER_BLOCKS)
.value(INCLUDE_OTHER_BLOCKS_DEFAULT)
.commandLineArgument(Loader.COMMAND_LINE_ARG_PREFIX + "-includeOtherBlocks")
.build());
options.add(
new Option(DISCARDABLE_SEGMENT_SIZE_OPTION_NAME, DEFAULT_DISCARDABLE_SEGMENT_SIZE,
Integer.class, Loader.COMMAND_LINE_ARG_PREFIX + "-maxSegmentDiscardSize"));
options.add(Option.newInteger(DISCARDABLE_SEGMENT_SIZE_OPTION_NAME)
.value(DEFAULT_DISCARDABLE_SEGMENT_SIZE)
.commandLineArgument(Loader.COMMAND_LINE_ARG_PREFIX + "-maxSegmentDiscardSize")
.build());
if (extensionAdapter != null) {
extensionAdapter.addLoadOptions(elf, options);
@@ -275,18 +275,13 @@ public class IntelHexLoader extends AbstractProgramLoader {
ArrayList<Option> list = new ArrayList<Option>();
if (loadIntoProgram) {
list.add(new Option(OPTION_NAME_IS_OVERLAY, isOverlay));
list.add(new Option(OPTION_NAME_BLOCK_NAME, blockName));
list.add(Option.newBoolean(OPTION_NAME_IS_OVERLAY).value(isOverlay).build());
list.add(Option.newString(OPTION_NAME_BLOCK_NAME).value(blockName).build());
}
else {
isOverlay = false;
}
if (baseAddr == null) {
list.add(new Option(OPTION_NAME_BASE_ADDRESS, Address.class));
}
else {
list.add(new Option(OPTION_NAME_BASE_ADDRESS, baseAddr));
}
list.add(Option.newAddress(OPTION_NAME_BASE_ADDRESS).value(baseAddr).build());
return list;
}
@@ -275,6 +275,18 @@ public interface Loader extends ExtensionPoint, Comparable<Loader> {
return false;
}
/**
* {@return the given argument with {@link #COMMAND_LINE_ARG_PREFIX} prepended}
* <p>
* This is a convenience method to make working with {@link Loader} command line options less
* verbose.
*
* @param arg the argument
*/
public default String createArg(String arg) {
return COMMAND_LINE_ARG_PREFIX + arg;
}
@Override
public default int compareTo(Loader o) {
int compareTiers = getTier().compareTo(o.getTier());
@@ -149,8 +149,11 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
List<Option> list = super.getDefaultOptions(provider, loadSpec, domainObject,
loadIntoProgram, mirrorFsLayout);
if (!loadIntoProgram) {
list.add(new Option(REEXPORT_OPTION_NAME, REEXPORT_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-reexport"));
list.add(Option.newBoolean(REEXPORT_OPTION_NAME)
.value(REEXPORT_OPTION_DEFAULT)
.commandLineArgument(createArg("-reexport"))
.description("Transitively export symbols from LC_REEXPORT_DYLIB libraries.")
.build());
}
return list;
}
@@ -435,18 +435,13 @@ public class MotorolaHexLoader extends AbstractProgramLoader {
ArrayList<Option> list = new ArrayList<Option>();
if (loadIntoProgram) {
list.add(new Option(OPTION_NAME_IS_OVERLAY, isOverlay));
list.add(new Option(OPTION_NAME_BLOCK_NAME, blockName));
list.add(Option.newBoolean(OPTION_NAME_IS_OVERLAY).value(isOverlay).build());
list.add(Option.newString(OPTION_NAME_BLOCK_NAME).value(blockName).build());
}
else {
isOverlay = false;
}
if (baseAddr == null) {
list.add(new Option(OPTION_NAME_BASE_ADDRESS, Address.class));
}
else {
list.add(new Option(OPTION_NAME_BASE_ADDRESS, baseAddr));
}
list.add(Option.newAddress(OPTION_NAME_BASE_ADDRESS).value(baseAddr).build());
return list;
}
@@ -193,8 +193,10 @@ public class PeLoader extends AbstractPeDebugLoader {
List<Option> list = super.getDefaultOptions(provider, loadSpec, domainObject,
loadIntoProgram, mirrorFsLayout);
if (!loadIntoProgram) {
list.add(new Option(PARSE_CLI_HEADERS_OPTION_NAME, PARSE_CLI_HEADERS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-parseCliHeaders"));
list.add(Option.newBoolean(PARSE_CLI_HEADERS_OPTION_NAME)
.value(PARSE_CLI_HEADERS_OPTION_DEFAULT)
.commandLineArgument(createArg("-parseCliHeaders"))
.build());
}
return list;
}
@@ -124,8 +124,10 @@ public class UnixAoutLoader extends AbstractProgramWrapperLoader {
}
List<Option> list = new ArrayList<Option>();
list.add(new Option(OPTION_NAME_BASE_ADDR, baseAddr, Address.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-baseAddr"));
list.add(Option.newAddress(OPTION_NAME_BASE_ADDR)
.value(baseAddr)
.commandLineArgument(createArg("-baseAddr"))
.build());
list.addAll(super.getDefaultOptions(provider, loadSpec, domainObject, loadIntoProgram,
mirrorFsLayout));
@@ -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.
@@ -104,48 +104,76 @@ public class XmlProgramOptions {
public List<Option> getOptions(boolean isAddToProgram) {
this.addToProgram = isAddToProgram;
ArrayList<Option> optionList = new ArrayList<>();
List<Option> optionList = new ArrayList<>();
optionList.add(new Option("Memory Blocks", Boolean.valueOf(isMemoryBlocks())));
optionList.add(new Option("Memory Contents", Boolean.valueOf(isMemoryContents())));
optionList.add(Option.newBoolean("Memory Blocks")
.value(isMemoryBlocks())
.build());
optionList.add(Option.newBoolean("Memory Contents")
.value(isMemoryContents())
.build());
optionList.add(Option.newBoolean("Instructions")
.value(isInstructions())
.build());
optionList.add(Option.newBoolean("Data")
.value(isData())
.build());
optionList.add(Option.newBoolean("Symbols")
.value(isSymbols())
.build());
optionList.add(Option.newBoolean("Equates")
.value(isEquates())
.build());
optionList.add(Option.newBoolean("Comments")
.value(isComments())
.build());
optionList.add(Option.newBoolean("Properties")
.value(isProperties())
.build());
optionList.add(Option.newBoolean("Bookmarks")
.value(isBookmarks())
.build());
optionList.add(Option.newBoolean("Trees")
.value(isTrees())
.build());
optionList.add(Option.newBoolean("References")
.value(isReferences())
.build());
optionList.add(Option.newBoolean("Functions")
.value(isFunctions())
.build());
optionList.add(Option.newBoolean("Registers")
.value(isRegisters())
.build());
optionList.add(Option.newBoolean("Relocation Table")
.value(isRelocationTable())
.build());
optionList.add(Option.newBoolean("Entry Points")
.value(isEntryPoints())
.build());
optionList.add(Option.newBoolean("External Libraries")
.value(isExternalLibraries())
.build());
if (isAddToProgram) {
optionList.add(new Option("Overwrite Memory Conflicts",
Boolean.valueOf(isOverwriteMemoryConflicts())));
optionList.add(Option.newBoolean("Overwrite Memory Conflicts")
.value(isOverwriteMemoryConflicts())
.build());
optionList.add(Option.newBoolean("Overwrite Data Conflicts")
.value(isOverwriteDataConflicts())
.build());
optionList.add(Option.newBoolean("Overwrite Symbol Conflicts")
.value(isOverwriteSymbolConflicts())
.build());
optionList.add(Option.newBoolean("Overwrite Property Conflicts")
.value(isOverwritePropertyConflicts())
.build());
optionList.add(Option.newBoolean("Overwrite Bookmark Conflicts")
.value(isOverwriteBookmarkConflicts())
.build());
optionList.add(Option.newBoolean("Overwrite Reference Conflicts")
.value(isOverwriteReferenceConflicts())
.build());
}
optionList.add(new Option("Instructions", Boolean.valueOf(isInstructions())));
optionList.add(new Option("Data", Boolean.valueOf(isData())));
if (isAddToProgram) {
optionList.add(
new Option("Overwrite Data Conflicts", Boolean.valueOf(isOverwriteDataConflicts())));
}
optionList.add(new Option("Symbols", Boolean.valueOf(isSymbols())));
if (isAddToProgram) {
optionList.add(new Option("Overwrite Symbol Conflicts",
Boolean.valueOf(isOverwriteSymbolConflicts())));
}
optionList.add(new Option("Equates", Boolean.valueOf(isEquates())));
optionList.add(new Option("Comments", Boolean.valueOf(isComments())));
optionList.add(new Option("Properties", Boolean.valueOf(isProperties())));
if (isAddToProgram) {
optionList.add(new Option("Overwrite Property Conflicts",
Boolean.valueOf(isOverwritePropertyConflicts())));
}
optionList.add(new Option("Bookmarks", Boolean.valueOf(isBookmarks())));
if (isAddToProgram) {
optionList.add(new Option("Overwrite Bookmark Conflicts",
Boolean.valueOf(isOverwriteBookmarkConflicts())));
}
optionList.add(new Option("Trees", Boolean.valueOf(isTrees())));
optionList.add(new Option("References", Boolean.valueOf(isReferences())));
if (isAddToProgram) {
optionList.add(new Option("Overwrite Reference Conflicts",
Boolean.valueOf(isOverwriteReferenceConflicts())));
}
optionList.add(new Option("Functions", Boolean.valueOf(isFunctions())));
optionList.add(new Option("Registers", Boolean.valueOf(isRegisters())));
optionList.add(new Option("Relocation Table", Boolean.valueOf(isRelocationTable())));
optionList.add(new Option("Entry Points", Boolean.valueOf(isEntryPoints())));
optionList.add(new Option("External Libraries", Boolean.valueOf(isExternalLibraries())));
return optionList;
}
@@ -355,13 +355,27 @@ public class CppExporter extends Exporter {
@Override
public List<Option> getOptions(DomainObjectService domainObjectService) {
ArrayList<Option> list = new ArrayList<>();
list.add(new Option(CREATE_HEADER_FILE, Boolean.valueOf(isCreateHeaderFile)));
list.add(new Option(CREATE_C_FILE, Boolean.valueOf(isCreateCFile)));
list.add(new Option(USE_CPP_STYLE_COMMENTS, Boolean.valueOf(isUseCppStyleComments)));
list.add(new Option(EMIT_TYPE_DEFINITONS, Boolean.valueOf(emitDataTypeDefinitions)));
list.add(new Option(EMIT_REFERENCED_GLOBALS, Boolean.valueOf(emitReferencedGlobals)));
list.add(new Option(FUNCTION_TAG_FILTERS, tagOptions));
list.add(new Option(FUNCTION_TAG_EXCLUDE, Boolean.valueOf(excludeMatchingTags)));
list.add(Option.newBoolean(CREATE_HEADER_FILE)
.value(isCreateHeaderFile)
.build());
list.add(Option.newBoolean(CREATE_C_FILE)
.value(isCreateCFile)
.build());
list.add(Option.newBoolean(USE_CPP_STYLE_COMMENTS)
.value(isUseCppStyleComments)
.build());
list.add(Option.newBoolean(EMIT_TYPE_DEFINITONS)
.value(emitDataTypeDefinitions)
.build());
list.add(Option.newBoolean(EMIT_REFERENCED_GLOBALS)
.value(emitReferencedGlobals)
.build());
list.add(Option.newString(FUNCTION_TAG_FILTERS)
.value(tagOptions)
.build());
list.add(Option.newBoolean(FUNCTION_TAG_EXCLUDE)
.value(excludeMatchingTags)
.build());
return list;
}
@@ -142,24 +142,38 @@ public class DyldCacheExtractLoader extends MachoLoader {
public List<Option> getDefaultOptions(ByteProvider provider, LoadSpec loadSpec,
DomainObject domainObject, boolean loadIntoProgram, boolean mirrorFsLayout) {
List<Option> list = new ArrayList<>();
list.add(new Option(LIBOBJC_OPTION_NAME, !loadIntoProgram && LIBOBJC_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-libobjc"));
list.add(new Option(AUTH_DATA_OPTION_NAME, !loadIntoProgram && AUTH_DATA_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-authData"));
list.add(new Option(DIRTY_DATA_OPTION_NAME, !loadIntoProgram && DIRTY_DATA_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-dirtyData"));
list.add(new Option(CONST_DATA_OPTION_NAME, !loadIntoProgram && CONST_DATA_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-constData"));
list.add(new Option(TEXT_STUBS_OPTION_NAME, !loadIntoProgram && TEXT_STUBS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-textStubs"));
list.add(new Option(CONFIG_DATA_OPTION_NAME, !loadIntoProgram && CONFIG_DATA_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-configData"));
list.add(new Option(READ_ONLY_DATA_OPTION_NAME,
!loadIntoProgram && READ_ONLY_DATA_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-readOnlyData"));
list.add(new Option(CONST_TPRO_DATA_OPTION_NAME,
!loadIntoProgram && CONST_TPRO_DATA_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-constTproData"));
list.add(Option.newBoolean(LIBOBJC_OPTION_NAME)
.value(!loadIntoProgram && LIBOBJC_OPTION_DEFAULT)
.commandLineArgument(createArg("-libobjc"))
.build());
list.add(Option.newBoolean(AUTH_DATA_OPTION_NAME)
.value(!loadIntoProgram && AUTH_DATA_OPTION_DEFAULT)
.commandLineArgument(createArg("-authData"))
.build());
list.add(Option.newBoolean(DIRTY_DATA_OPTION_NAME)
.value(!loadIntoProgram && DIRTY_DATA_OPTION_DEFAULT)
.commandLineArgument(createArg("-dirtyData"))
.build());
list.add(Option.newBoolean(CONST_DATA_OPTION_NAME)
.value(!loadIntoProgram && CONST_DATA_OPTION_DEFAULT)
.commandLineArgument(createArg("-constData"))
.build());
list.add(Option.newBoolean(TEXT_STUBS_OPTION_NAME)
.value(!loadIntoProgram && TEXT_STUBS_OPTION_DEFAULT)
.commandLineArgument(createArg("-textStubs"))
.build());
list.add(Option.newBoolean(CONFIG_DATA_OPTION_NAME)
.value(!loadIntoProgram && CONFIG_DATA_OPTION_DEFAULT)
.commandLineArgument(createArg("-configData"))
.build());
list.add(Option.newBoolean(READ_ONLY_DATA_OPTION_NAME)
.value(!loadIntoProgram && READ_ONLY_DATA_OPTION_DEFAULT)
.commandLineArgument(createArg("-readOnlyData"))
.build());
list.add(Option.newBoolean(CONST_TPRO_DATA_OPTION_NAME)
.value(!loadIntoProgram && CONST_TPRO_DATA_OPTION_DEFAULT)
.commandLineArgument(createArg("-constTproData"))
.build());
return list;
}
@@ -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.
@@ -317,12 +317,17 @@ public class DumpFile {
protected static Collection<? extends Option> getDefaultOptions(DumpFileReader reader) {
List<Option> list = new ArrayList<>();
list.add(new Option(CREATE_MEMORY_BLOCKS_OPTION_NAME, CREATE_MEMORY_BLOCKS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-createMemoryBlocks"));
list.add(new Option(JOIN_BLOCKS_OPTION_NAME, JOIN_BLOCKS_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-joinBlocks"));
list.add(new Option(ANALYZE_EMBEDDED_OBJECTS_OPTION_NAME,
ANALYZE_EMBEDDED_OBJECTS_OPTION_DEFAULT));
list.add(Option.newBoolean(CREATE_MEMORY_BLOCKS_OPTION_NAME)
.value(CREATE_MEMORY_BLOCKS_OPTION_DEFAULT)
.commandLineArgument(Loader.COMMAND_LINE_ARG_PREFIX + "-createMemoryBlocks")
.build());
list.add(Option.newBoolean(JOIN_BLOCKS_OPTION_NAME)
.value(JOIN_BLOCKS_OPTION_DEFAULT)
.commandLineArgument(Loader.COMMAND_LINE_ARG_PREFIX + "-joinBlocks")
.build());
list.add(Option.newBoolean(ANALYZE_EMBEDDED_OBJECTS_OPTION_NAME)
.value(ANALYZE_EMBEDDED_OBJECTS_OPTION_DEFAULT)
.build());
return list;
}
@@ -85,8 +85,9 @@ public class Apport extends DumpFile {
DecodedProvider provider =
new DecodedProvider(this, reader.getByteProvider(), monitor)) {
ElfLoader elfLoader = new ElfLoader();
Option base = new Option(ElfLoaderOptionsFactory.IMAGE_BASE_OPTION_NAME,
Long.toHexString(header.getMemoryInfo(0).getBaseAddress()));
Option base = Option.newString(ElfLoaderOptionsFactory.IMAGE_BASE_OPTION_NAME)
.value(Long.toHexString(header.getMemoryInfo(0).getBaseAddress()))
.build();
options.add(base);
program.addConsumer(consumer);
ImporterSettings settings = new ImporterSettings(provider, program.getName(), null,
@@ -192,8 +193,10 @@ public class Apport extends DumpFile {
public static Collection<? extends Option> getDefaultOptions(DumpFileReader reader) {
List<Option> list = new ArrayList<>();
list.add(new Option(CREATE_MEMORY_BLOCKS_OPTION_NAME, CREATE_MEMORY_BLOCKS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-createMemoryBlocks"));
list.add(Option.newBoolean(CREATE_MEMORY_BLOCKS_OPTION_NAME)
.value(CREATE_MEMORY_BLOCKS_OPTION_DEFAULT)
.commandLineArgument(Loader.COMMAND_LINE_ARG_PREFIX + "-createMemoryBlocks")
.build());
return list;
}
@@ -612,8 +612,10 @@ public class Pagedump extends DumpFile {
List<Option> list = new ArrayList<>();
list.add(new Option(DEBUG_DATA_PATH_OPTION_NAME, DEBUG_DATA_PATH_OPTION_DEFAULT,
String.class, Loader.COMMAND_LINE_ARG_PREFIX + "-debugDataFilePath"));
list.add(Option.newString(DEBUG_DATA_PATH_OPTION_NAME)
.value(DEBUG_DATA_PATH_OPTION_DEFAULT)
.commandLineArgument(Loader.COMMAND_LINE_ARG_PREFIX + "-debugDataFilePath")
.build());
list.addAll(DumpFile.getDefaultOptions(reader));
@@ -107,50 +107,82 @@ public class SarifProgramOptions {
public List<Option> getOptions(boolean isAddToProgram) {
this.addToProgram = isAddToProgram;
ArrayList<Option> optionList = new ArrayList<>();
List<Option> optionList = new ArrayList<>();
optionList.add(new Option("Memory Blocks", Boolean.valueOf(isMemoryBlocks())));
optionList.add(new Option("Memory Contents", Boolean.valueOf(isMemoryContents())));
optionList.add(Option.newBoolean("Memory Blocks")
.value(isMemoryBlocks())
.build());
optionList.add(Option.newBoolean("Memory Contents")
.value(isMemoryContents())
.build());
optionList.add(Option.newBoolean("Instructions")
.value(isInstructions())
.build());
optionList.add(Option.newBoolean("Data")
.value(isData())
.build());
optionList.add(Option.newBoolean("Symbols")
.value(isSymbols())
.build());
optionList.add(Option.newBoolean("Equates")
.value(isEquates())
.build());
optionList.add(Option.newBoolean("Comments")
.value(isComments())
.build());
optionList.add(Option.newBoolean("Properties")
.value(isProperties())
.build());
optionList.add(Option.newBoolean("Bookmarks")
.value(isBookmarks())
.build());
optionList.add(Option.newBoolean("Trees")
.value(isTrees())
.build());
optionList.add(Option.newBoolean("References")
.value(isReferences())
.build());
optionList.add(Option.newBoolean("Functions")
.value(isFunctions())
.build());
optionList.add(Option.newBoolean("Registers")
.value(isRegisters())
.build());
optionList.add(Option.newBoolean("Relocation Table")
.value(isRelocationTable())
.build());
optionList.add(Option.newBoolean("Entry Points")
.value(isEntryPoints())
.build());
optionList.add(Option.newBoolean("External Libraries")
.value(isExternalLibraries())
.build());
optionList.add(Option.newBoolean(AbstractProgramLoader.APPLY_LABELS_OPTION_NAME)
.value(applyProcDefinedLabels())
.build());
optionList.add(Option.newBoolean(AbstractProgramLoader.ANCHOR_LABELS_OPTION_NAME)
.value(anchorProcDefinedLabels())
.build());
if (isAddToProgram) {
optionList.add(new Option("Overwrite Memory Conflicts",
Boolean.valueOf(isOverwriteMemoryConflicts())));
optionList.add(Option.newBoolean("Overwrite Memory Conflicts")
.value(isOverwriteMemoryConflicts())
.build());
optionList.add(Option.newBoolean("Overwrite Data Conflicts")
.value(isOverwriteDataConflicts())
.build());
optionList.add(Option.newBoolean("Overwrite Symbol Conflicts")
.value(isOverwriteSymbolConflicts())
.build());
optionList.add(Option.newBoolean("Overwrite Property Conflicts")
.value(isOverwritePropertyConflicts())
.build());
optionList.add(Option.newBoolean("Overwrite Bookmark Conflicts")
.value(isOverwriteBookmarkConflicts())
.build());
optionList.add(Option.newBoolean("Overwrite Reference Conflicts")
.value(isOverwriteReferenceConflicts())
.build());
}
optionList.add(new Option("Instructions", Boolean.valueOf(isInstructions())));
optionList.add(new Option("Data", Boolean.valueOf(isData())));
if (isAddToProgram) {
optionList.add(
new Option("Overwrite Data Conflicts", Boolean.valueOf(isOverwriteDataConflicts())));
}
optionList.add(new Option("Symbols", Boolean.valueOf(isSymbols())));
if (isAddToProgram) {
optionList.add(new Option("Overwrite Symbol Conflicts",
Boolean.valueOf(isOverwriteSymbolConflicts())));
}
optionList.add(new Option("Equates", Boolean.valueOf(isEquates())));
optionList.add(new Option("Comments", Boolean.valueOf(isComments())));
optionList.add(new Option("Properties", Boolean.valueOf(isProperties())));
if (isAddToProgram) {
optionList.add(new Option("Overwrite Property Conflicts",
Boolean.valueOf(isOverwritePropertyConflicts())));
}
optionList.add(new Option("Bookmarks", Boolean.valueOf(isBookmarks())));
if (isAddToProgram) {
optionList.add(new Option("Overwrite Bookmark Conflicts",
Boolean.valueOf(isOverwriteBookmarkConflicts())));
}
optionList.add(new Option("Trees", Boolean.valueOf(isTrees())));
optionList.add(new Option("References", Boolean.valueOf(isReferences())));
if (isAddToProgram) {
optionList.add(new Option("Overwrite Reference Conflicts",
Boolean.valueOf(isOverwriteReferenceConflicts())));
}
optionList.add(new Option("Functions", Boolean.valueOf(isFunctions())));
optionList.add(new Option("Registers", Boolean.valueOf(isRegisters())));
optionList.add(new Option("Relocation Table", Boolean.valueOf(isRelocationTable())));
optionList.add(new Option("Entry Points", Boolean.valueOf(isEntryPoints())));
optionList.add(new Option("External Libraries", Boolean.valueOf(isExternalLibraries())));
optionList.add(new Option(AbstractProgramLoader.APPLY_LABELS_OPTION_NAME, Boolean.valueOf(applyProcDefinedLabels())));
optionList.add(new Option(AbstractProgramLoader.ANCHOR_LABELS_OPTION_NAME, Boolean.valueOf(anchorProcDefinedLabels())));
return optionList;
}
@@ -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.
@@ -98,9 +98,10 @@ public class ARM_ElfExtension extends ElfExtension {
Msg.warn(this, "Failed to fully parse ELF headers to formulate ARM import options");
}
options.add(new Option(APPLY_PC_BIAS_TO_RELATIVE_RELOCATIONS_OPTION_NAME,
enablePcBiasOption, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-applyArmElfRelocPCBias"));
options.add(Option.newBoolean(APPLY_PC_BIAS_TO_RELATIVE_RELOCATIONS_OPTION_NAME)
.value(enablePcBiasOption)
.commandLineArgument(Loader.COMMAND_LINE_ARG_PREFIX + "-applyArmElfRelocPCBias")
.build());
}
@Override
@@ -64,7 +64,9 @@ public class SkeletonExporter extends Exporter {
List<Option> list = new ArrayList<>();
// If this exporter has custom options, add them to 'list'
list.add(new Option("Option name goes here", "Default option value goes here"));
list.add(Option.newString("Option name goes here")
.value("Default option value goes here")
.build());
return list;
}
@@ -63,7 +63,9 @@ public class SkeletonLoader extends AbstractProgramWrapperLoader {
isLoadIntoProgram, mirrorFsLayout);
// If this loader has custom options, add them to 'list'
list.add(new Option("Option name goes here", "Default option value goes here"));
list.add(Option.newString("Option name goes here")
.value("Default option value goes here")
.build());
return list;
}