From 325c48e904dbf153eb1576a1ac2eb897bc240d09 Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Mon, 8 Jan 2024 14:47:33 -0500 Subject: [PATCH] GP-4152 added ability for ELF extension to specify default image base --- .../bin/format/elf/extend/ElfLoadAdapter.java | 11 +++ .../util/opinion/ElfLoaderOptionsFactory.java | 16 +++- .../elf/extend/MSP430_ElfExtension.java | 88 +++++++++++++++++++ .../TI_MSP430X_ElfRelocationHandler.java | 7 +- .../TI_MSP430_ElfRelocationHandler.java | 5 +- 5 files changed, 117 insertions(+), 10 deletions(-) create mode 100644 Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/extend/MSP430_ElfExtension.java diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/extend/ElfLoadAdapter.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/extend/ElfLoadAdapter.java index 1e77400ce7..fbf0019266 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/extend/ElfLoadAdapter.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/extend/ElfLoadAdapter.java @@ -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 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 70b1128fd7..8b6d8d48d2 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 @@ -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); } diff --git a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/extend/MSP430_ElfExtension.java b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/extend/MSP430_ElfExtension.java new file mode 100644 index 0000000000..4deddf40b9 --- /dev/null +++ b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/extend/MSP430_ElfExtension.java @@ -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; + } + +} diff --git a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/TI_MSP430X_ElfRelocationHandler.java b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/TI_MSP430X_ElfRelocationHandler.java index 5eda2e8e3d..eaca68a4e8 100644 --- a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/TI_MSP430X_ElfRelocationHandler.java +++ b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/TI_MSP430X_ElfRelocationHandler.java @@ -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 diff --git a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/TI_MSP430_ElfRelocationHandler.java b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/TI_MSP430_ElfRelocationHandler.java index bf54fbf3cc..ac779f23f3 100644 --- a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/TI_MSP430_ElfRelocationHandler.java +++ b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/TI_MSP430_ElfRelocationHandler.java @@ -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