diff --git a/Ghidra/Features/Base/src/main/help/help/topics/ImporterPlugin/importer.htm b/Ghidra/Features/Base/src/main/help/help/topics/ImporterPlugin/importer.htm
index 20f9a560bf..fb439d9c46 100644
--- a/Ghidra/Features/Base/src/main/help/help/topics/ImporterPlugin/importer.htm
+++ b/Ghidra/Features/Base/src/main/help/help/topics/ImporterPlugin/importer.htm
@@ -384,6 +384,16 @@
the program is run. These sections will not be stored in a special address space called
"other".
+
+
Max Zero-Segment Discard Size
+
+
+
When both section-headers and program-headers are present, this option controls the
+ maximum byte-size of a non-section-based memory block which has a zero-fill which will
+ be discarded. This is intended to allow section-alignment load sequences to be ignored
+ and discarded. A value of "0" will disable all such discards. The default value is
+ 255-bytes.
+
Intel Hex Options
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfLoaderOptionsFactory.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfLoaderOptionsFactory.java
index 0d8dd66d08..e93a3d15fd 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfLoaderOptionsFactory.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfLoaderOptionsFactory.java
@@ -47,6 +47,14 @@ public class ElfLoaderOptionsFactory {
public static final String INCLUDE_OTHER_BLOCKS = "Import Non-Loaded Data";// as OTHER overlay blocks
static final boolean INCLUDE_OTHER_BLOCKS_DEFAULT = true;
+ public static final String DISCARDABLE_SEGMENT_SIZE_OPTION_NAME =
+ "Max Zero-Segment Discard Size";
+
+ // Maximum length of discardable segment
+ // If program contains section headers, any zeroed segment smaller than this size
+ // will be eligible for removal.
+ private static final int DEFAULT_DISCARDABLE_SEGMENT_SIZE = 0xff;
+
private ElfLoaderOptionsFactory() {
}
@@ -82,6 +90,10 @@ public class ElfLoaderOptionsFactory {
options.add(new Option(INCLUDE_OTHER_BLOCKS, INCLUDE_OTHER_BLOCKS_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-includeOtherBlocks"));
+ options.add(
+ new Option(DISCARDABLE_SEGMENT_SIZE_OPTION_NAME, DEFAULT_DISCARDABLE_SEGMENT_SIZE,
+ Integer.class, Loader.COMMAND_LINE_ARG_PREFIX + "-maxSegmentDiscardSize"));
+
ElfLoadAdapter extensionAdapter = ElfExtensionFactory.getLoadAdapter(elf);
if (extensionAdapter != null) {
extensionAdapter.addLoadOptions(elf, options);
@@ -166,10 +178,27 @@ public class ElfLoaderOptionsFactory {
}
}
else if (name.equals(IMAGE_BASE_OPTION_NAME)) {
- return validateAddressSpaceOffsetOption(option, language.getDefaultSpace());
+ String err = validateAddressSpaceOffsetOption(option, language.getDefaultSpace());
+ if (err != null) {
+ return err;
+ }
}
else if (name.equals(IMAGE_DATA_IMAGE_BASE_OPTION_NAME)) {
- return validateAddressSpaceOffsetOption(option, language.getDefaultDataSpace());
+ String err =
+ validateAddressSpaceOffsetOption(option, language.getDefaultDataSpace());
+ if (err != null) {
+ return err;
+ }
+ }
+ else if (name.equals(DISCARDABLE_SEGMENT_SIZE_OPTION_NAME)) {
+ if (!Integer.class.isAssignableFrom(option.getValueClass())) {
+ return "Invalid type for option: " + name + " - " + option.getValueClass();
+ }
+ int val = (Integer) option.getValue();
+ if (val < 0 || val > DEFAULT_DISCARDABLE_SEGMENT_SIZE) {
+ return "Option value out-of-range: " + name + " (0.." +
+ DEFAULT_DISCARDABLE_SEGMENT_SIZE + ")";
+ }
}
}
return null;
@@ -214,4 +243,9 @@ public class ElfLoaderOptionsFactory {
return OptionUtils.getOption(IMAGE_DATA_IMAGE_BASE_OPTION_NAME, options, (String) null);
}
+ public static int getMaxSegmentDiscardSize(List