mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
88570bf43e
4 changed files with 88 additions and 84 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue