Merge remote-tracking branch 'origin/patch'

This commit is contained in:
ghidra1 2022-07-20 12:37:32 -04:00
commit 88570bf43e
4 changed files with 88 additions and 84 deletions

View file

@ -169,7 +169,7 @@ public class ElfSectionHeaderConstants {
/**Processor-specific*/ /**Processor-specific*/
public static final int SHF_MASKPROC = 0xf0000000; public static final int SHF_MASKPROC = 0xf0000000;
// // Special section index values (stored as 16-bit value)
/**undefined, missing, irrelevant section*/ /**undefined, missing, irrelevant section*/
public static final short SHN_UNDEF = (short) 0x0000; public static final short SHN_UNDEF = (short) 0x0000;
@ -198,7 +198,7 @@ public class ElfSectionHeaderConstants {
* specific value in the range SHN_LOPROC..SHN_HIPROC, else false * specific value in the range SHN_LOPROC..SHN_HIPROC, else false
*/ */
public static boolean isProcessorSpecificSymbolSectionIndex(short symbolSectionIndex) { public static boolean isProcessorSpecificSymbolSectionIndex(short symbolSectionIndex) {
return symbolSectionIndex >= ElfSectionHeaderConstants.SHN_LOPROC && return (Short.compareUnsigned(symbolSectionIndex, SHN_LOPROC) >= 0) &&
symbolSectionIndex <= ElfSectionHeaderConstants.SHN_HIPROC; (Short.compareUnsigned(symbolSectionIndex, SHN_HIPROC) <= 0);
} }
} }

View file

@ -191,13 +191,11 @@ public class ElfSymbol implements ByteArrayConverter {
if (st_name == 0) { if (st_name == 0) {
if (getType() == STT_SECTION) { if (getType() == STT_SECTION) {
ElfSectionHeader[] sections = header.getSections(); ElfSectionHeader[] sections = header.getSections();
if (st_shndx < 0 || st_shndx >= sections.length) { // FIXME: handle extended section indexing
//invalid section reference... int uSectionIndex = Short.toUnsignedInt(st_shndx);
//this is a bug in objcopy, whereby sections are removed if (Short.compareUnsigned(st_shndx, ElfSectionHeaderConstants.SHN_LORESERVE) < 0 &&
//but the corresponding section symbols are left behind. uSectionIndex < sections.length) {
} ElfSectionHeader section = sections[uSectionIndex];
else {
ElfSectionHeader section = sections[st_shndx];
nameAsString = section.getNameAsString(); nameAsString = section.getNameAsString();
} }
} }
@ -345,7 +343,7 @@ public class ElfSymbol implements ByteArrayConverter {
public boolean isExternal() { public boolean isExternal() {
return (isGlobal() || isWeak()) && getValue() == 0 && getSize() == 0 && return (isGlobal() || isWeak()) && getValue() == 0 && getSize() == 0 &&
getType() == STT_NOTYPE && getType() == STT_NOTYPE &&
getSectionHeaderIndex() == ElfSectionHeaderConstants.SHT_NULL; getSectionHeaderIndex() == ElfSectionHeaderConstants.SHN_UNDEF;
} }
/** /**
@ -473,6 +471,7 @@ public class ElfSymbol implements ByteArrayConverter {
/** /**
* Every symbol table entry is "defined" in relation to some section; * Every symbol table entry is "defined" in relation to some section;
* this member holds the relevant section header table index. * this member holds the relevant section header table index.
* NOTE: This value reflects the raw st_shndx value and not the extended section index value
* @return the relevant section header table index * @return the relevant section header table index
*/ */
public short getSectionHeaderIndex() { public short getSectionHeaderIndex() {
@ -504,10 +503,11 @@ public class ElfSymbol implements ByteArrayConverter {
*/ */
@Override @Override
public String toString() { public String toString() {
return nameAsString + " - " + "st_value:" + Long.toHexString(st_value) + " - " + return nameAsString + " - " + "st_value: 0x" + Long.toHexString(st_value) + " - " +
"st_size: " + Long.toHexString(st_size) + " - " + "st_info: " + "st_size: 0x" + Long.toHexString(st_size) + " - " + "st_info: 0x" +
Integer.toHexString(st_info) + " - " + "st_other: " + Integer.toHexString(st_other) + Integer.toHexString(Byte.toUnsignedInt(st_info)) + " - " + "st_other: 0x" +
" - " + "st_shndx:" + Integer.toHexString(st_shndx); Integer.toHexString(Byte.toUnsignedInt(st_other)) +
" - " + "st_shndx: 0x" + Integer.toHexString(Short.toUnsignedInt(st_shndx));
} }
/** /**

View file

@ -341,7 +341,7 @@ public class ElfLoadAdapter {
* adjust the address and/or apply context to the intended symbol location. * adjust the address and/or apply context to the intended symbol location.
* @param elfLoadHelper load helper object * @param elfLoadHelper load helper object
* @param elfSymbol elf symbol * @param elfSymbol elf symbol
* @param address program memory address where symbol will be created * @param address program memory address where symbol will be created.
* @param isExternal true if symbol treated as external to the program and has been * @param isExternal true if symbol treated as external to the program and has been
* assigned a fake memory address in the EXTERNAL memory block. * assigned a fake memory address in the EXTERNAL memory block.
* @return adjusted symbol address or null if extension will handle applying the elfSymbol * @return adjusted symbol address or null if extension will handle applying the elfSymbol

View file

@ -1522,7 +1522,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
usingFakeExternal = true; usingFakeExternal = true;
} }
if (elfSymbol.isObject()) { if (elfSymbol.isObject() && address.isMemoryAddress()) {
long size = elfSymbol.getSize(); long size = elfSymbol.getSize();
if (size > 0 && size < Integer.MAX_VALUE) { if (size > 0 && size < Integer.MAX_VALUE) {
dataAllocationMap.put(address, (int) size); dataAllocationMap.put(address, (int) size);
@ -1581,30 +1581,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
AddressSpace symbolSpace = defaultSpace; AddressSpace symbolSpace = defaultSpace;
long symOffset = elfSymbol.getValue(); long symOffset = elfSymbol.getValue();
if (sectionIndex > 0) { boolean isAllocatedToSection = false;
if (sectionIndex < elfSections.length) { if (sectionIndex == ElfSectionHeaderConstants.SHN_UNDEF) { // Not section relative 0x0000 (e.g., no sections defined)
ElfSectionHeader symSection = elf.getSections()[sectionIndex];
symSectionBase = findLoadAddress(symSection, 0);
if (symSectionBase == null) {
log("Unable to place symbol due to non-loaded section: " +
elfSymbol.getNameAsString() + " - value=0x" +
Long.toHexString(elfSymbol.getValue()) + ", section=" +
symSection.getNameAsString());
return null;
}
symbolSpace = symSectionBase.getAddressSpace();
} // else assume sections have been stripped
AddressSpace space = symbolSpace.getPhysicalSpace();
symOffset = loadAdapter.getAdjustedMemoryOffset(symOffset, space);
if (space == defaultSpace) {
symOffset =
elf.adjustAddressForPrelink(symOffset) + getImageBaseWordAdjustmentOffset();
}
else if (space == defaultDataSpace) {
symOffset += getImageDataBase();
}
}
else if (sectionIndex == ElfSectionHeaderConstants.SHN_UNDEF) { // Not section relative 0x0000 (e.g., no sections defined)
Address regAddr = findMemoryRegister(elfSymbol); Address regAddr = findMemoryRegister(elfSymbol);
if (regAddr != null) { if (regAddr != null) {
@ -1617,39 +1595,82 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
symOffset = loadAdapter.getAdjustedMemoryOffset(symOffset, defaultSpace); symOffset = loadAdapter.getAdjustedMemoryOffset(symOffset, defaultSpace);
symOffset += getImageBaseWordAdjustmentOffset(); symOffset += getImageBaseWordAdjustmentOffset();
} }
else if (sectionIndex == ElfSectionHeaderConstants.SHN_ABS) { // Absolute value/address - 0xfff1 else if (Short.compareUnsigned(sectionIndex, ElfSectionHeaderConstants.SHN_LORESERVE) < 0) {
// TODO: Which space ? Can't distinguish simple constant vs. data vs. code/default space isAllocatedToSection = true;
// The should potentially be assign a constant address instead (not possible currently) int uSectionIndex = Short.toUnsignedInt(sectionIndex);
if (uSectionIndex < elfSections.length) {
// Note: Assume data space - symbols will be "pinned" ElfSectionHeader symSection = elf.getSections()[uSectionIndex];
symSectionBase = findLoadAddress(symSection, 0);
if (symSectionBase == null) {
log("Unable to place symbol due to non-loaded section: " +
elfSymbol.getNameAsString() + " - value=0x" +
Long.toHexString(elfSymbol.getValue()) + ", section=" +
symSection.getNameAsString());
return null;
}
// TODO: it may be inappropriate to adjust since value may not actually be a memory address - what to do? symbolSpace = symSectionBase.getAddressSpace();
// symOffset = loadAdapter.adjustMemoryOffset(symOffset, space);
Address regAddr = findMemoryRegister(elfSymbol); if (elf.isRelocatable()) {
if (regAddr != null) { // Section relative symbol - ensure that symbol remains in
return regAddr; // overlay space even if beyond bounds of associated block
// Note: don't use symOffset variable since it may have been
// adjusted for image base
return symSectionBase.addWrapSpace(elfSymbol.getValue() *
symSectionBase.getAddressSpace().getAddressableUnitSize());
}
} }
symbolSpace = getConstantSpace(); // Unable to place symbol within relocatable if section missing/stripped
else if (elf.isRelocatable()) {
log("No Memory for symbol: " + elfSymbol.getNameAsString() +
" - 0x" + Long.toHexString(elfSymbol.getValue()));
return null;
}
AddressSpace space = symbolSpace.getPhysicalSpace();
symOffset = loadAdapter.getAdjustedMemoryOffset(symOffset, space);
if (space == defaultSpace) {
symOffset =
elf.adjustAddressForPrelink(symOffset) + getImageBaseWordAdjustmentOffset();
}
else if (space == defaultDataSpace) {
symOffset += getImageDataBase();
}
}
else if (sectionIndex == ElfSectionHeaderConstants.SHN_ABS) { // Absolute value/address - 0xfff1
byte type = elfSymbol.getType();
if (type == ElfSymbol.STT_FILE) {
return null; // ignore file symbol
}
// Absolute symbols will be pinned to associated address
symbolSpace = defaultDataSpace;
if (elfSymbol.isFunction()) {
symbolSpace = defaultSpace;
}
else {
Address regAddr = findMemoryRegister(elfSymbol);
if (regAddr != null) {
return regAddr;
}
}
} }
else if (sectionIndex == ElfSectionHeaderConstants.SHN_COMMON) { // Common symbols - 0xfff2 ( else if (sectionIndex == ElfSectionHeaderConstants.SHN_COMMON) { // Common symbols - 0xfff2 (
// TODO: Which space ? Can't distinguish data vs. code/default space return Address.NO_ADDRESS; // assume unallocated/external
// I believe COMMON symbols must be allocated based upon their size. These symbols
// during the linking phase will generally be placed into a data section (e.g., .data, .bss)
} }
else { // TODO: Identify which cases if any that this is valid else { // TODO: Identify which cases if any that this is valid
// SHN_LORESERVE 0xff00 // SHN_LORESERVE 0xff00
// SHN_LOPROC 0xff00 // SHN_LOPROC 0xff00
// SHN_HIPROC 0xff1f // SHN_HIPROC 0xff1f
// SHN_COMMON 0xfff2
// SHN_HIRESERVE 0xffff // SHN_HIRESERVE 0xffff
log("Unable to place symbol: " + elfSymbol.getNameAsString() + log("Unable to place symbol: " + elfSymbol.getNameAsString() +
" - value=0x" + Long.toHexString(elfSymbol.getValue()) + ", section-index=0x" + " - value=0x" + Long.toHexString(elfSymbol.getValue()) + ", section-index=0x" +
Integer.toHexString(sectionIndex & 0xffff)); Integer.toHexString(Short.toUnsignedInt(sectionIndex)));
return null; return null;
} }
@ -1659,35 +1680,15 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
address = symbolSpace.getAddressInThisSpaceOnly(address.getOffset()); address = symbolSpace.getAddressInThisSpaceOnly(address.getOffset());
} }
if (elfSymbol.isAbsolute()) { if (isAllocatedToSection || elfSymbol.isAbsolute()) {
// TODO: Many absolute values do not refer to memory at all return address;
// should we exclude certain absolute symbols (e.g., 0, 1)? }
//we will just use the symbols preferred address... // Identify special cases which should be treated as external (return NO_ADDRESS)
}
else if (elfSymbol.isExternal() || elfSymbol.isCommon()) { if (elfSymbol.isExternal()) {
return Address.NO_ADDRESS; return Address.NO_ADDRESS;
} }
else if (elf.isRelocatable()) {
if (sectionIndex < 0 || sectionIndex >= elfSections.length) {
log("Error creating symbol: " + elfSymbol.getNameAsString() +
" - 0x" + Long.toHexString(elfSymbol.getValue()));
return Address.NO_ADDRESS;
}
else if (symSectionBase == null) {
log("No Memory for symbol: " + elfSymbol.getNameAsString() +
" - 0x" + Long.toHexString(elfSymbol.getValue()));
return Address.NO_ADDRESS;
}
else {
// Section relative symbol - ensure that symbol remains in
// overlay space even if beyond bounds of associated block
// Note: don't use symOffset variable since it may have been
// adjusted for image base
address = symSectionBase.addWrapSpace(elfSymbol.getValue() *
symSectionBase.getAddressSpace().getAddressableUnitSize());
}
}
else if (!elfSymbol.isSection() && elfSymbol.getValue() == 0) { else if (!elfSymbol.isSection() && elfSymbol.getValue() == 0) {
return Address.NO_ADDRESS; return Address.NO_ADDRESS;
} }
@ -1870,7 +1871,10 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
throws InvalidInputException { throws InvalidInputException {
// allow extension to either modify symbol address or fully handle it // allow extension to either modify symbol address or fully handle it
address = elf.getLoadAdapter().evaluateElfSymbol(this, elfSymbol, address, isFakeExternal); if (address.isMemoryAddress()) {
address =
elf.getLoadAdapter().evaluateElfSymbol(this, elfSymbol, address, isFakeExternal);
}
if (address != null) { if (address != null) {
// Remember where in memory Elf symbols have been mapped // Remember where in memory Elf symbols have been mapped