GP-4152 added ability for ELF extension to specify default image base

This commit is contained in:
ghidra1
2024-01-08 14:47:33 -05:00
parent 1e82a772c5
commit 325c48e904
5 changed files with 117 additions and 10 deletions

View File

@@ -24,6 +24,7 @@ import java.util.*;
import ghidra.app.util.Option;
import ghidra.app.util.bin.format.MemoryLoadable;
import ghidra.app.util.bin.format.elf.*;
import ghidra.app.util.opinion.ElfLoaderOptionsFactory;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.listing.Program;
@@ -530,6 +531,16 @@ public class ElfLoadAdapter {
// no additional options
}
/**
* Get the default image base to be used when one cannot be determined.
* @param elfHeader ELF header
* @return default image base
*/
public long getDefaultImageBase(ElfHeader elfHeader) {
return elfHeader.is64Bit() ? ElfLoaderOptionsFactory.IMAGE64_BASE_DEFAULT
: ElfLoaderOptionsFactory.IMAGE32_BASE_DEFAULT;
}
/**
* Get the section-relative offset for the specified ELF symbol which is bound to
* the specified section. If the symbol has an absolute symbol value/offset this method

View File

@@ -42,7 +42,8 @@ public class ElfLoaderOptionsFactory {
// an assumed virtual memory of 32-bits.
public static final String IMAGE_BASE_OPTION_NAME = "Image Base";
public static final long IMAGE_BASE_DEFAULT = 0x00010000;
public static final long IMAGE16_BASE_DEFAULT = 0x00001000;
public static final long IMAGE32_BASE_DEFAULT = 0x00010000;
public static final long IMAGE64_BASE_DEFAULT = 0x00100000L;
public static final String IMAGE_DATA_IMAGE_BASE_OPTION_NAME = "Data Image Base";
@@ -74,12 +75,20 @@ public class ElfLoaderOptionsFactory {
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-applyUndefinedData"));
ElfHeader elf = new ElfHeader(provider, null);
ElfLoadAdapter extensionAdapter = ElfExtensionFactory.getLoadAdapter(elf);
Language language = loadSpec.getLanguageCompilerSpec().getLanguage();
long imageBase = elf.findImageBase();
if (imageBase == 0 && (elf.isRelocatable() || elf.isSharedObject())) {
imageBase = elf.is64Bit() ? IMAGE64_BASE_DEFAULT : IMAGE_BASE_DEFAULT;
if (extensionAdapter != null) {
imageBase = extensionAdapter.getDefaultImageBase(elf);
}
else {
imageBase = elf.is64Bit() ? IMAGE64_BASE_DEFAULT : IMAGE32_BASE_DEFAULT;
}
}
Language language = loadSpec.getLanguageCompilerSpec().getLanguage();
AddressSpace defaultSpace = language.getDefaultSpace();
String hexValueStr = getBaseAddressOffsetString(imageBase, defaultSpace);
@@ -101,7 +110,6 @@ public class ElfLoaderOptionsFactory {
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);
}

View File

@@ -0,0 +1,88 @@
/* ###
* 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.bin.format.elf.extend;
import ghidra.app.util.bin.format.elf.*;
import ghidra.app.util.opinion.ElfLoaderOptionsFactory;
import ghidra.program.model.lang.Language;
public class MSP430_ElfExtension extends ElfExtension {
public static final int E_MSP430_MACH = 0xff;
public static final int E_MSP430_MACH_MSP430X = 45; // 20-bit extended, all others are 16-bit
// Elf Section Header Extensions
public static final ElfSectionHeaderType SHT_MSP430_ATTRIBUTES = new ElfSectionHeaderType(
0x70000003, "SHT_MSP430_ATTRIBUTES", "Section contains ABI attributes");
public static final ElfSectionHeaderType SHT_MSP430_SEC_FLAGS = new ElfSectionHeaderType(
0x70000005, "SHT_MSP430_SEC_FLAGS", "Section contains compiler's section flags");
public static final ElfSectionHeaderType SHT_MSP430_SYM_ALIASES = new ElfSectionHeaderType(
0x70000006, "SHT_MSP430_SYM_ALIASES", "Section contains compiler's symbol aliases");
// Attribute section values
public static final int OFBA_MSPABI_Tag_ISA = 4;
public static final int OFBA_MSPABI_Tag_Code_Model = 6;
public static final int OFBA_MSPABI_Tag_Data_Model = 8;
public static final int OFBA_MSPABI_Tag_enum_size = 10;
// Values defined for OFBA_MSPABI_Tag_ISA
public static final int OFBA_MSPABI_Val_ISA_NONE = 0;
public static final int OFBA_MSPABI_Val_ISA_MSP430 = 1;
public static final int OFBA_MSPABI_Val_ISA_MSP430X = 2;
// Values defined for OFBA_MSPABI_Tag_Code_Model. */
public static final int OFBA_MSPABI_Val_Code_Model_NONE = 0;
public static final int OFBA_MSPABI_Val_Code_Model_SMALL = 1;
public static final int OFBA_MSPABI_Val_Code_Model_LARGE = 2;
// Values defined for OFBA_MSPABI_Tag_Data_Model. */
public static final int OFBA_MSPABI_Val_Data_Model_NONE = 0;
public static final int OFBA_MSPABI_Val_Data_Model_SMALL = 1;
public static final int OFBA_MSPABI_Val_Data_Model_LARGE = 2;
public static final int OFBA_MSPABI_Val_Data_Model_RESTRICTED = 3; /* Unused by GNU. */
// Values defined for Tag_GNU_MSP430_Data_Region
public static final int Val_GNU_MSP430_Data_Region_NONE = 0;
// The default data region. Assumes all data is below address 0x10000
public static final int Val_GNU_MSP430_Data_Region_Lower = 1;
// Set if -mdata-region={none;upper;either}. Assumes data could be placed at or above address 0x10000
public static final int Val_GNU_MSP430_Data_Region_Any = 2;
@Override
public boolean canHandle(ElfHeader elf) {
return elf.e_machine() == ElfConstants.EM_MSP430;
}
@Override
public boolean canHandle(ElfLoadHelper elfLoadHelper) {
Language language = elfLoadHelper.getProgram().getLanguage();
return canHandle(elfLoadHelper.getElfHeader()) &&
"TI_MSP430".equals(language.getProcessor().toString());
}
@Override
public String getDataTypeSuffix() {
return "_MSP430";
}
@Override
public long getDefaultImageBase(ElfHeader elfHeader) {
// same default used for 16 and 20-bit space
return ElfLoaderOptionsFactory.IMAGE16_BASE_DEFAULT;
}
}

View File

@@ -16,6 +16,7 @@
package ghidra.app.util.bin.format.elf.relocation;
import ghidra.app.util.bin.format.elf.*;
import ghidra.app.util.bin.format.elf.extend.MSP430_ElfExtension;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.Memory;
@@ -26,12 +27,10 @@ import ghidra.util.exception.NotFoundException;
public class TI_MSP430X_ElfRelocationHandler extends ElfRelocationHandler {
public static final int E_MSP430_MACH_MSP430X = 45;
@Override
public boolean canRelocate(ElfHeader elf) {
return (elf.e_machine() == ElfConstants.EM_MSP430) &&
((elf.e_flags() & 0xff) == E_MSP430_MACH_MSP430X);
return (elf.e_machine() == ElfConstants.EM_MSP430) && ((elf.e_flags() &
MSP430_ElfExtension.E_MSP430_MACH) == MSP430_ElfExtension.E_MSP430_MACH_MSP430X);
}
@Override

View File

@@ -16,6 +16,7 @@
package ghidra.app.util.bin.format.elf.relocation;
import ghidra.app.util.bin.format.elf.*;
import ghidra.app.util.bin.format.elf.extend.MSP430_ElfExtension;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.Memory;
@@ -28,8 +29,8 @@ public class TI_MSP430_ElfRelocationHandler extends ElfRelocationHandler {
@Override
public boolean canRelocate(ElfHeader elf) {
return (elf.e_machine() == ElfConstants.EM_MSP430) &&
((elf.e_flags() & 0xff) != TI_MSP430X_ElfRelocationHandler.E_MSP430_MACH_MSP430X);
return (elf.e_machine() == ElfConstants.EM_MSP430) && ((elf.e_flags() &
MSP430_ElfExtension.E_MSP430_MACH) != MSP430_ElfExtension.E_MSP430_MACH_MSP430X);
}
@Override