mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
Merge remote-tracking branch
'origin/GP-664_ghidra1_ELF_MIPSSymbolResolution'
This commit is contained in:
commit
cc81544a14
4 changed files with 71 additions and 13 deletions
|
@ -191,4 +191,14 @@ public class ElfSectionHeaderConstants {
|
|||
public static final short SHN_XINDEX = (short) 0xffff;
|
||||
/**upper bound on range of reserved indexes*/
|
||||
public static final short SHN_HIRESERVE = (short) 0xffff;
|
||||
|
||||
/**
|
||||
* @param symbolSectionIndex symbol section index (st_shndx)
|
||||
* @return true if specified symbol section index corresponds to a processor
|
||||
* specific value in the range SHN_LOPROC..SHN_HIPROC, else false
|
||||
*/
|
||||
public static boolean isProcessorSpecificSymbolSectionIndex(short symbolSectionIndex) {
|
||||
return symbolSectionIndex >= ElfSectionHeaderConstants.SHN_LOPROC &&
|
||||
symbolSectionIndex <= ElfSectionHeaderConstants.SHN_HIPROC;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -312,6 +312,22 @@ public class ElfLoadAdapter {
|
|||
return functionAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows an extension to override the default address calculation for loading
|
||||
* a symbol. This is generally only neccessary when symbol requires handling of processor-specific
|
||||
* flags or section index. This method should return null when default symbol processing
|
||||
* is sufficient. {@link Address#NO_ADDRESS} should be returned if the symbol is external
|
||||
* and is not handled by default processing.
|
||||
* @param elfLoadHelper load helper object
|
||||
* @param elfSymbol elf symbol
|
||||
* @return symbol memory address or null to defer to default implementation
|
||||
* @throws NoValueException if error logged and address calculation failed
|
||||
*/
|
||||
public Address calculateSymbolAddress(ElfLoadHelper elfLoadHelper, ElfSymbol elfSymbol)
|
||||
throws NoValueException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* During symbol processing this method will be invoked to permit an extension to
|
||||
* adjust the address and/or apply context to the intended symbol location.
|
||||
|
@ -487,4 +503,5 @@ public class ElfLoadAdapter {
|
|||
public Class<? extends ElfRelocation> getRelocationClass(ElfHeader elfHeader) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.io.InputStream;
|
|||
import java.math.BigInteger;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import ghidra.app.cmd.label.SetLabelPrimaryCmd;
|
||||
import ghidra.app.util.MemoryBlockUtils;
|
||||
|
@ -1232,7 +1231,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
|||
monitor.checkCanceled();
|
||||
try {
|
||||
|
||||
Address address = calculateSymbolAddress(elfSymbol, msg -> log(msg));
|
||||
Address address = calculateSymbolAddress(elfSymbol);
|
||||
if (address == null) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1280,11 +1279,10 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
|||
/**
|
||||
* Calculate the load address associated with a specified elfSymbol.
|
||||
* @param elfSymbol ELF symbol
|
||||
* @param errorConsumer error consumer
|
||||
* @return symbol address or null if symbol not supported and address not determined,
|
||||
* or NO_ADDRESS if symbol is external and should be allocated to the EXTERNAL block.
|
||||
* or {@link Address#NO_ADDRESS} if symbol is external and should be allocated to the EXTERNAL block.
|
||||
*/
|
||||
private Address calculateSymbolAddress(ElfSymbol elfSymbol, Consumer<String> errorConsumer) {
|
||||
private Address calculateSymbolAddress(ElfSymbol elfSymbol) {
|
||||
|
||||
if (elfSymbol.getSymbolTableIndex() == 0) {
|
||||
return null; // always skip the first symbol, it is NULL
|
||||
|
@ -1296,13 +1294,23 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
|||
|
||||
if (elfSymbol.isTLS()) {
|
||||
// TODO: Investigate support for TLS symbols
|
||||
errorConsumer.accept(
|
||||
"Unsupported Thread-Local Symbol not loaded: " + elfSymbol.getNameAsString());
|
||||
log("Unsupported Thread-Local Symbol not loaded: " + elfSymbol.getNameAsString());
|
||||
return null;
|
||||
}
|
||||
|
||||
ElfLoadAdapter loadAdapter = elf.getLoadAdapter();
|
||||
|
||||
// Allow extension to have first shot at calculating symbol address
|
||||
try {
|
||||
Address address = elf.getLoadAdapter().calculateSymbolAddress(this, elfSymbol);
|
||||
if (address != null) {
|
||||
return address;
|
||||
}
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ElfSectionHeader[] elfSections = elf.getSections();
|
||||
short sectionIndex = elfSymbol.getSectionHeaderIndex();
|
||||
Address symSectionBase = null;
|
||||
|
@ -1316,7 +1324,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
|||
ElfSectionHeader symSection = elf.getSections()[sectionIndex];
|
||||
symSectionBase = findLoadAddress(symSection, 0);
|
||||
if (symSectionBase == null) {
|
||||
errorConsumer.accept("Unable to place symbol due to non-loaded section: " +
|
||||
log("Unable to place symbol due to non-loaded section: " +
|
||||
elfSymbol.getNameAsString() + " - value=0x" +
|
||||
Long.toHexString(elfSymbol.getValue()) + ", section=" +
|
||||
symSection.getNameAsString());
|
||||
|
@ -1366,7 +1374,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
|||
// SHN_COMMON 0xfff2
|
||||
// SHN_HIRESERVE 0xffff
|
||||
|
||||
errorConsumer.accept("Unable to place symbol: " + elfSymbol.getNameAsString() +
|
||||
log("Unable to place symbol: " + elfSymbol.getNameAsString() +
|
||||
" - value=0x" + Long.toHexString(elfSymbol.getValue()) + ", section-index=0x" +
|
||||
Integer.toHexString(sectionIndex & 0xffff));
|
||||
return null;
|
||||
|
@ -1389,12 +1397,12 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
|||
}
|
||||
else if (elf.isRelocatable()) {
|
||||
if (sectionIndex < 0 || sectionIndex >= elfSections.length) {
|
||||
errorConsumer.accept("Error creating symbol: " + elfSymbol.getNameAsString() +
|
||||
log("Error creating symbol: " + elfSymbol.getNameAsString() +
|
||||
" - 0x" + Long.toHexString(elfSymbol.getValue()));
|
||||
return Address.NO_ADDRESS;
|
||||
}
|
||||
else if (symSectionBase == null) {
|
||||
errorConsumer.accept("No Memory for symbol: " + elfSymbol.getNameAsString() +
|
||||
log("No Memory for symbol: " + elfSymbol.getNameAsString() +
|
||||
" - 0x" + Long.toHexString(elfSymbol.getValue()));
|
||||
return Address.NO_ADDRESS;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ import ghidra.util.exception.*;
|
|||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class MIPS_ElfExtension extends ElfExtension {
|
||||
|
||||
|
||||
private static final String MIPS_STUBS_SECTION_NAME = ".MIPS.stubs";
|
||||
|
||||
// GP value reflected by symbol address
|
||||
|
@ -287,9 +287,13 @@ public class MIPS_ElfExtension extends ElfExtension {
|
|||
public static final byte ODK_IDENT = 10;
|
||||
public static final byte ODK_PAGESIZE = 11;
|
||||
|
||||
// MIPS-specific SHN values
|
||||
public static final short SHN_MIPS_ACOMMON = (short) 0xff00;
|
||||
public static final short SHN_MIPS_TEXT = (short) 0xff01;
|
||||
public static final short SHN_MIPS_DATA = (short) 0xff02;
|
||||
|
||||
@Override
|
||||
public boolean canHandle(ElfHeader elf) {
|
||||
// TODO: Verify 64-bit MIPS support
|
||||
return elf.e_machine() == ElfConstants.EM_MIPS;
|
||||
}
|
||||
|
||||
|
@ -328,6 +332,25 @@ public class MIPS_ElfExtension extends ElfExtension {
|
|||
return functionAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Address calculateSymbolAddress(ElfLoadHelper elfLoadHelper, ElfSymbol elfSymbol)
|
||||
throws NoValueException {
|
||||
|
||||
short sectionIndex = elfSymbol.getSectionHeaderIndex();
|
||||
if (!ElfSectionHeaderConstants.isProcessorSpecificSymbolSectionIndex(sectionIndex)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (sectionIndex == SHN_MIPS_ACOMMON || sectionIndex == SHN_MIPS_TEXT || sectionIndex == SHN_MIPS_DATA) {
|
||||
// NOTE: logic assumes no memory conflict occured during section loading
|
||||
AddressSpace defaultSpace = elfLoadHelper.getProgram().getAddressFactory().getDefaultAddressSpace();
|
||||
return defaultSpace.getAddress(elfSymbol.getValue() + elfLoadHelper.getImageBaseWordAdjustmentOffset());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Address evaluateElfSymbol(ElfLoadHelper elfLoadHelper, ElfSymbol elfSymbol,
|
||||
Address address, boolean isExternal) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue