Merge remote-tracking branch

'origin/GP-664_ghidra1_ELF_MIPSSymbolResolution'
This commit is contained in:
ghidra1 2021-02-10 20:04:37 -05:00
commit cc81544a14
4 changed files with 71 additions and 13 deletions

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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) {