mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Merge remote-tracking branch
'origin/GP-3428_ghidra1_ELFSegmentDiscardSize' into patch (Closes #5273)
This commit is contained in:
commit
5b53757dc6
4 changed files with 51 additions and 8 deletions
|
@ -384,6 +384,16 @@
|
||||||
the program is run. These sections will not be stored in a special address space called
|
the program is run. These sections will not be stored in a special address space called
|
||||||
"other".</P>
|
"other".</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<H4>Max Zero-Segment Discard Size</H4>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>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.</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<H3>Intel Hex Options<A name="Options_Intel_Hex"/></H3>
|
<H3>Intel Hex Options<A name="Options_Intel_Hex"/></H3>
|
||||||
|
|
|
@ -47,6 +47,14 @@ public class ElfLoaderOptionsFactory {
|
||||||
public static final String INCLUDE_OTHER_BLOCKS = "Import Non-Loaded Data";// as OTHER overlay blocks
|
public static final String INCLUDE_OTHER_BLOCKS = "Import Non-Loaded Data";// as OTHER overlay blocks
|
||||||
static final boolean INCLUDE_OTHER_BLOCKS_DEFAULT = true;
|
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() {
|
private ElfLoaderOptionsFactory() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +90,10 @@ public class ElfLoaderOptionsFactory {
|
||||||
options.add(new Option(INCLUDE_OTHER_BLOCKS, INCLUDE_OTHER_BLOCKS_DEFAULT, Boolean.class,
|
options.add(new Option(INCLUDE_OTHER_BLOCKS, INCLUDE_OTHER_BLOCKS_DEFAULT, Boolean.class,
|
||||||
Loader.COMMAND_LINE_ARG_PREFIX + "-includeOtherBlocks"));
|
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);
|
ElfLoadAdapter extensionAdapter = ElfExtensionFactory.getLoadAdapter(elf);
|
||||||
if (extensionAdapter != null) {
|
if (extensionAdapter != null) {
|
||||||
extensionAdapter.addLoadOptions(elf, options);
|
extensionAdapter.addLoadOptions(elf, options);
|
||||||
|
@ -166,10 +178,27 @@ public class ElfLoaderOptionsFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (name.equals(IMAGE_BASE_OPTION_NAME)) {
|
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)) {
|
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;
|
return null;
|
||||||
|
@ -214,4 +243,9 @@ public class ElfLoaderOptionsFactory {
|
||||||
return OptionUtils.getOption(IMAGE_DATA_IMAGE_BASE_OPTION_NAME, options, (String) null);
|
return OptionUtils.getOption(IMAGE_DATA_IMAGE_BASE_OPTION_NAME, options, (String) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getMaxSegmentDiscardSize(List<Option> options) {
|
||||||
|
return OptionUtils.getOption(DISCARDABLE_SEGMENT_SIZE_OPTION_NAME, options,
|
||||||
|
DEFAULT_DISCARDABLE_SEGMENT_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,11 +70,6 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||||
private static final String ELF_PROGRAM_HEADERS_BLOCK_NAME = "_elfProgramHeaders";
|
private static final String ELF_PROGRAM_HEADERS_BLOCK_NAME = "_elfProgramHeaders";
|
||||||
private static final String ELF_SECTION_HEADERS_BLOCK_NAME = "_elfSectionHeaders";
|
private static final String ELF_SECTION_HEADERS_BLOCK_NAME = "_elfSectionHeaders";
|
||||||
|
|
||||||
// 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 DISCARDABLE_SEGMENT_SIZE = 0xff;
|
|
||||||
|
|
||||||
private List<Option> options;
|
private List<Option> options;
|
||||||
private Long dataImageBase; // cached data image base option or null if not applicable
|
private Long dataImageBase; // cached data image base option or null if not applicable
|
||||||
private MessageLog log;
|
private MessageLog log;
|
||||||
|
@ -326,7 +321,10 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||||
if (elf.getSectionHeaderCount() == 0 || elf.getProgramHeaderCount() == 0) {
|
if (elf.getSectionHeaderCount() == 0 || elf.getProgramHeaderCount() == 0) {
|
||||||
return false; // only prune if both sections and program headers are present
|
return false; // only prune if both sections and program headers are present
|
||||||
}
|
}
|
||||||
if (length > DISCARDABLE_SEGMENT_SIZE || !blockName.startsWith(SEGMENT_NAME_PREFIX)) {
|
|
||||||
|
int maxSegmentDiscardSize = ElfLoaderOptionsFactory.getMaxSegmentDiscardSize(options);
|
||||||
|
if (maxSegmentDiscardSize <= 0 || length > maxSegmentDiscardSize ||
|
||||||
|
!blockName.startsWith(SEGMENT_NAME_PREFIX)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -600,6 +600,7 @@ The Headless Analyzer uses the command-line parameters discussed below. See <a h
|
||||||
<LI><typewriter>-loader-imagebase <imagebase<sup>3</sup>></typewriter></LI>
|
<LI><typewriter>-loader-imagebase <imagebase<sup>3</sup>></typewriter></LI>
|
||||||
<LI><typewriter>-loader-dataImageBase <dataImageBase<sup>4</sup>></typewriter></LI>
|
<LI><typewriter>-loader-dataImageBase <dataImageBase<sup>4</sup>></typewriter></LI>
|
||||||
<LI><typewriter>-loader-includeOtherBlocks <true|false></typewriter></LI>
|
<LI><typewriter>-loader-includeOtherBlocks <true|false></typewriter></LI>
|
||||||
|
<LI><typewriter>-loader-maxSegmentDiscardSize <0..255> (default: 255)</typewriter></LI>
|
||||||
</UL>
|
</UL>
|
||||||
<LI><typewriter>-loader PeLoader<typewriter></LI>
|
<LI><typewriter>-loader PeLoader<typewriter></LI>
|
||||||
<UL>
|
<UL>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue