diff --git a/Ghidra/Features/Base/src/main/help/help/topics/MemoryMapPlugin/Memory_Map.htm b/Ghidra/Features/Base/src/main/help/help/topics/MemoryMapPlugin/Memory_Map.htm index 4122b8f3f6..14bc73febb 100644 --- a/Ghidra/Features/Base/src/main/help/help/topics/MemoryMapPlugin/Memory_Map.htm +++ b/Ghidra/Features/Base/src/main/help/help/topics/MemoryMapPlugin/Memory_Map.htm @@ -60,7 +60,7 @@ by importers. At this point in time there is no capability provided by the Memory Map provider to create a new File Bytes instance.

-

Overlay - Each of the above memory block types may optionally be specified as an Overlay at the +

Overlay - Each of the above memory block types may optionally be specified as an Overlay at the time of creation. If this option is selected, the block is created in a new overlay address space.  Overlay blocks can serve various purposes where a memory range may contain different data/code or map to different areas of memory diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/DWARFAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/DWARFAnalyzer.java index 9c10a8d872..45627bfbdf 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/DWARFAnalyzer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/DWARFAnalyzer.java @@ -27,6 +27,7 @@ import ghidra.app.util.importer.MessageLog; import ghidra.framework.options.Options; import ghidra.program.model.address.AddressSetView; import ghidra.program.model.data.BuiltInDataTypeManager; +import ghidra.program.model.lang.Language; import ghidra.program.model.listing.Program; import ghidra.util.Msg; import ghidra.util.exception.CancelledException; @@ -91,6 +92,15 @@ public class DWARFAnalyzer extends AbstractAnalyzer { setSupportsOneTimeAnalysis(); } + @Override + public boolean getDefaultEnablement(Program program) { + // TODO: DWARF implementation needs improvements to handle Harvard Architectures properly + // Currently unable to produce addresses which should refer to data space resulting in + // improperly placed symbols, etc. + Language language = program.getLanguage(); + return language.getDefaultSpace() == language.getDefaultDataSpace(); + } + @Override public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log) throws CancelledException { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/EntryPointAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/EntryPointAnalyzer.java index 8fd8b4d85e..ff24aec6d4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/EntryPointAnalyzer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/EntryPointAnalyzer.java @@ -443,7 +443,7 @@ public class EntryPointAnalyzer extends AbstractAnalyzer { } private boolean isLanguageDefinedEntry(Program program, Address addr) { - List labelList = program.getLanguage().getDefaultLabels(); + List labelList = program.getLanguage().getDefaultSymbols(); for (AddressLabelInfo info : labelList) { if (addr.equals(info.getAddress())) { return info.isEntry(); @@ -453,7 +453,7 @@ public class EntryPointAnalyzer extends AbstractAnalyzer { } private boolean isLanguageDefinedEntryPointer(Program program, Address addr) { - List labelList = program.getLanguage().getDefaultLabels(); + List labelList = program.getLanguage().getDefaultSymbols(); for (AddressLabelInfo info : labelList) { if (addr.equals(info.getAddress())) { ProcessorSymbolType type = info.getProcessorSymbolType(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/ParamInfo.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/ParamInfo.java index 481967b3d8..357b74d880 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/ParamInfo.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/ParamInfo.java @@ -110,6 +110,9 @@ public class ParamInfo { } void setOrdinal(int i) { + if (original != null && original.getOrdinal() != i) { + original = null; + } this.ordinal = i; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DIEAggregate.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DIEAggregate.java index 7eb530454e..7a160c2c9f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DIEAggregate.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DIEAggregate.java @@ -865,7 +865,7 @@ public class DIEAggregate { // if the DWARF attr was a DW_FORM_addr, it doesn't need fixing up if (high.form == DWARFForm.DW_FORM_addr) { - return highVal.getUnsignedValue() + getProgram().getProgramBaseAddressFixup(); + return highVal.getUnsignedValue() + getProgram().getProgramBaseAddressFixup() - 1; } // else it was a DW_FORM_data value and is relative to the lowPC value diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFFunctionImporter.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFFunctionImporter.java index d271e08899..786da2b95c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFFunctionImporter.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFFunctionImporter.java @@ -605,7 +605,7 @@ public class DWARFFunctionImporter { private final Address toAddr(Number offset) { return currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress( - offset.longValue()); + offset.longValue(), true); } /** diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfHeader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfHeader.java index d3aca3a02b..4eaa5ecdb2 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfHeader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfHeader.java @@ -630,12 +630,11 @@ public class ElfHeader implements StructConverter, Writeable { } ArrayList stringTableList = new ArrayList<>(); - for (int i = 0; i < sectionHeaders.length; ++i) { - if (sectionHeaders[i].getType() == ElfSectionHeaderConstants.SHT_STRTAB) { - ElfSectionHeader stringTableSectionHeader = sectionHeaders[i]; + for (ElfSectionHeader stringTableSectionHeader : sectionHeaders) { + if (stringTableSectionHeader.getType() == ElfSectionHeaderConstants.SHT_STRTAB) { ElfStringTable stringTable = ElfStringTable.createElfStringTable(reader, this, stringTableSectionHeader, stringTableSectionHeader.getOffset(), - sectionHeaders[i].getAddress(), stringTableSectionHeader.getSize()); + stringTableSectionHeader.getAddress(), stringTableSectionHeader.getSize()); stringTableList.add(stringTable); if (stringTable.getAddressOffset() == dynamicStringTableAddr) { dynamicStringTable = stringTable; @@ -703,10 +702,9 @@ public class ElfHeader implements StructConverter, Writeable { // Add section based symbol tables ArrayList symbolTableList = new ArrayList<>(); - for (int i = 0; i < sectionHeaders.length; ++i) { - if (sectionHeaders[i].getType() == ElfSectionHeaderConstants.SHT_SYMTAB || - sectionHeaders[i].getType() == ElfSectionHeaderConstants.SHT_DYNSYM) { - ElfSectionHeader symbolTableSectionHeader = sectionHeaders[i]; + for (ElfSectionHeader symbolTableSectionHeader : sectionHeaders) { + if (symbolTableSectionHeader.getType() == ElfSectionHeaderConstants.SHT_SYMTAB || + symbolTableSectionHeader.getType() == ElfSectionHeaderConstants.SHT_DYNSYM) { if (symbolTableSectionHeader.getOffset() < 0) { continue; } @@ -896,15 +894,15 @@ public class ElfHeader implements StructConverter, Writeable { // HACK: 07/01/2013 - Added hack for malformed ELF file with only program header sections ElfProgramHeader[] pheaders = getProgramHeaders(); long size = 0; - for (int i = 0; i < pheaders.length; i++) { - size += pheaders[i].getFileSize(); + for (ElfProgramHeader pheader : pheaders) { + size += pheader.getFileSize(); } if (size == fileLength) { // adjust program section file offset to be based on relative read offset long relOffset = 0; - for (int i = 0; i < pheaders.length; i++) { - pheaders[i].setOffset(relOffset); - relOffset += pheaders[i].getFileSize(); + for (ElfProgramHeader pheader : pheaders) { + pheader.setOffset(relOffset); + relOffset += pheader.getFileSize(); } } } @@ -1322,9 +1320,9 @@ public class ElfHeader implements StructConverter, Writeable { */ public ElfSectionHeader[] getSections(int type) { ArrayList list = new ArrayList<>(); - for (int i = 0; i < sectionHeaders.length; i++) { - if (sectionHeaders[i].getType() == type) { - list.add(sectionHeaders[i]); + for (ElfSectionHeader sectionHeader : sectionHeaders) { + if (sectionHeader.getType() == type) { + list.add(sectionHeader); } } ElfSectionHeader[] sections = new ElfSectionHeader[list.size()]; @@ -1340,15 +1338,17 @@ public class ElfHeader implements StructConverter, Writeable { */ public ElfSectionHeader getSection(String name) { List list = new ArrayList<>(); - for (int i = 0; i < sectionHeaders.length; i++) { - if (name != null && name.equals(sectionHeaders[i].getNameAsString())) { - list.add(sectionHeaders[i]); + for (ElfSectionHeader sectionHeader : sectionHeaders) { + if (name != null && name.equals(sectionHeader.getNameAsString())) { + list.add(sectionHeader); } } - if (list.size() == 0) + if (list.size() == 0) { return null; - if (list.size() > 1) + } + if (list.size() > 1) { throw new RuntimeException(">1 section with name of " + name); + } return list.get(0); } @@ -1359,9 +1359,9 @@ public class ElfHeader implements StructConverter, Writeable { * @return the section header with the specified address */ public ElfSectionHeader getSectionAt(long address) { - for (int i = 0; i < sectionHeaders.length; i++) { - if (sectionHeaders[i].getAddress() == address) { - return sectionHeaders[i]; + for (ElfSectionHeader sectionHeader : sectionHeaders) { + if (sectionHeader.getAddress() == address) { + return sectionHeader; } } return null; @@ -1375,14 +1375,14 @@ public class ElfHeader implements StructConverter, Writeable { */ public ElfSectionHeader getSectionLoadHeaderContaining(long address) { // FIXME: verify - for (int i = 0; i < sectionHeaders.length; i++) { - if (!sectionHeaders[i].isAlloc()) { + for (ElfSectionHeader sectionHeader : sectionHeaders) { + if (!sectionHeader.isAlloc()) { continue; } - long start = sectionHeaders[i].getAddress(); - long end = start + sectionHeaders[i].getSize(); + long start = sectionHeader.getAddress(); + long end = start + sectionHeader.getSize(); if (start <= address && address <= end) { - return sectionHeaders[i]; + return sectionHeader; } } return null; @@ -1447,9 +1447,9 @@ public class ElfHeader implements StructConverter, Writeable { */ public ElfProgramHeader[] getProgramHeaders(int type) { ArrayList list = new ArrayList<>(); - for (int i = 0; i < programHeaders.length; i++) { - if (programHeaders[i].getType() == type) { - list.add(programHeaders[i]); + for (ElfProgramHeader programHeader : programHeaders) { + if (programHeader.getType() == type) { + list.add(programHeader); } } ElfProgramHeader[] arr = new ElfProgramHeader[list.size()]; @@ -1487,9 +1487,9 @@ public class ElfHeader implements StructConverter, Writeable { * @return the program header with the specified address */ public ElfProgramHeader getProgramHeaderAt(long virtualAddr) { - for (int i = 0; i < programHeaders.length; i++) { - if (programHeaders[i].getVirtualAddress() == virtualAddr) { - return programHeaders[i]; + for (ElfProgramHeader programHeader : programHeaders) { + if (programHeader.getVirtualAddress() == virtualAddr) { + return programHeader; } } return null; @@ -1502,15 +1502,15 @@ public class ElfHeader implements StructConverter, Writeable { * @return the program header with the specified address */ public ElfProgramHeader getProgramLoadHeaderContaining(long virtualAddr) { - for (int i = 0; i < programHeaders.length; i++) { - if (programHeaders[i] == null || - programHeaders[i].getType() != ElfProgramHeaderConstants.PT_LOAD) { + for (ElfProgramHeader programHeader : programHeaders) { + if (programHeader == null || + programHeader.getType() != ElfProgramHeaderConstants.PT_LOAD) { continue; } - long start = programHeaders[i].getVirtualAddress(); - long end = programHeaders[i].getAdjustedMemorySize() - 1 + start; + long start = programHeader.getVirtualAddress(); + long end = programHeader.getAdjustedMemorySize() - 1 + start; if (virtualAddr >= start && virtualAddr <= end) { - return programHeaders[i]; + return programHeader; } } return null; @@ -1523,15 +1523,15 @@ public class ElfHeader implements StructConverter, Writeable { * @return the program header with the specified file offset */ public ElfProgramHeader getProgramLoadHeaderContainingFileOffset(long offset) { - for (int i = 0; i < programHeaders.length; i++) { - if (programHeaders[i] == null || - programHeaders[i].getType() != ElfProgramHeaderConstants.PT_LOAD) { + for (ElfProgramHeader programHeader : programHeaders) { + if (programHeader == null || + programHeader.getType() != ElfProgramHeaderConstants.PT_LOAD) { continue; } - long start = programHeaders[i].getOffset(); - long end = start + (programHeaders[i].getFileSize() - 1); + long start = programHeader.getOffset(); + long end = start + (programHeader.getFileSize() - 1); if (offset >= start && offset <= end) { - return programHeaders[i]; + return programHeader; } } return null; @@ -1567,9 +1567,9 @@ public class ElfHeader implements StructConverter, Writeable { * @return the string table associated to the specified section header */ public ElfStringTable getStringTable(ElfSectionHeader section) { - for (int i = 0; i < stringTables.length; i++) { - if (stringTables[i].getFileOffset() == section.getOffset()) { - return stringTables[i]; + for (ElfStringTable stringTable : stringTables) { + if (stringTable.getFileOffset() == section.getOffset()) { + return stringTable; } } return null; @@ -1600,9 +1600,9 @@ public class ElfHeader implements StructConverter, Writeable { if (symbolTableSection == null) { return null; } - for (int i = 0; i < symbolTables.length; i++) { - if (symbolTables[i].getFileOffset() == symbolTableSection.getOffset()) { - return symbolTables[i]; + for (ElfSymbolTable symbolTable : symbolTables) { + if (symbolTable.getFileOffset() == symbolTableSection.getOffset()) { + return symbolTable; } } return null; @@ -1633,9 +1633,9 @@ public class ElfHeader implements StructConverter, Writeable { * @return the relocation table located at the specified fileOffset or null */ public ElfRelocationTable getRelocationTableAtOffset(long fileOffset) { - for (int i = 0; i < relocationTables.length; i++) { - if (relocationTables[i].getFileOffset() == fileOffset) { - return relocationTables[i]; + for (ElfRelocationTable relocationTable : relocationTables) { + if (relocationTable.getFileOffset() == fileOffset) { + return relocationTable; } } return null; @@ -1707,7 +1707,7 @@ public class ElfHeader implements StructConverter, Writeable { * @return e_entry component ordinal */ public int getEntryComponentOrdinal() { - return 9; + return 11; } /** @@ -1716,7 +1716,7 @@ public class ElfHeader implements StructConverter, Writeable { * @return e_phoff component ordinal */ public int getPhoffComponentOrdinal() { - return 10; + return 12; } /** @@ -1725,7 +1725,7 @@ public class ElfHeader implements StructConverter, Writeable { * @return e_shoff component ordinal */ public int getShoffComponentOrdinal() { - return 11; + return 13; } private void addSection(ElfSectionHeader newSection) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationContext.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationContext.java index 020c76ffd8..e11895122d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationContext.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationContext.java @@ -259,4 +259,14 @@ public class ElfRelocationContext { } } + /** + * Get relocation address + * @param baseAddress base address + * @param relocOffset relocation offset relative to baseAddress + * @return relocation address + */ + public Address getRelocationAddress(Address baseAddress, long relocOffset) { + return baseAddress.addWrap(relocOffset); + } + } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/AbstractProgramLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/AbstractProgramLoader.java index 4e9b49c389..cd7c8fd959 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/AbstractProgramLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/AbstractProgramLoader.java @@ -179,7 +179,8 @@ public abstract class AbstractProgramLoader implements Loader { public List

  • -loader-applyRelocations <true|false>
  • -loader-imagebase <imagebase3>
  • +
  • -loader-dataImageBase <dataImageBase4>
  • -loader-includeOtherBlocks <true|false>
  • -loader-resolveExternalSymbols <true|false>
  • @@ -609,9 +610,11 @@ The Headless Analyzer uses the command-line parameters discussed below. See

    - 1. Address must be in the form [space:]offset. Space is optional, and offset is a hex value with no leading 0x.
    - 2. To specify hexadecimal, use a leading 0x.
    - 3. Address is in the default space, and must be specified as a hexadecimal value without the leading 0x.
    + 1Address must be in the form [space:]offset. Space is optional, and offset is a hex value with no leading 0x.
    + 2To specify hexadecimal, use a leading 0x.
    + 3Base address is in the default space and must be specified as a hexadecimal value without the leading 0x.
    + 4Base address is in the default data space and must be specified as a hexadecimal value without the leading 0x. + This option only applies to Harvard Architecture processors when loading relocatable ELF binaries (i.e., object modules).