Corrected recently introduced ElfLoader bug causing non-loaded sections

to be improperly loaded into memory
This commit is contained in:
ghidra1
2019-09-09 11:28:50 -04:00
parent 15c1f43fa5
commit 1194474767
3 changed files with 84 additions and 80 deletions
@@ -125,17 +125,15 @@ public class ElfLoadAdapter {
}
/**
* Get the preferred load address space for a program segment
* Get the preferred load address space for an allocated program segment.
* The OTHER space is reserved and should not be returned by this method.
* @param elfLoadHelper load helper object
* @param elfProgramHeader elf program segment header
* @return preferred load address space or null to use default behavior
*/
public AddressSpace getPreferredSegmentAddressSpace(ElfLoadHelper elfLoadHelper,
ElfProgramHeader elfProgramHeader) {
if (elfProgramHeader.getType() != ElfProgramHeaderConstants.PT_LOAD &&
elfProgramHeader.getVirtualAddress() == 0) {
return AddressSpace.OTHER_SPACE;
}
Program program = elfLoadHelper.getProgram();
if (elfProgramHeader.isExecute()) {
return program.getAddressFactory().getDefaultAddressSpace();
@@ -143,7 +141,6 @@ public class ElfLoadAdapter {
// segment is not marked execute, use the data space by default
return program.getLanguage().getDefaultDataSpace();
}
/**
* Get the preferred load address for a program segment
@@ -151,20 +148,20 @@ public class ElfLoadAdapter {
* @param elfProgramHeader elf program segment header
* @return preferred load address
*/
public Address getPreferredSegmentAddress(ElfLoadHelper elfLoadHelper, ElfProgramHeader elfProgramHeader) {
public Address getPreferredSegmentAddress(ElfLoadHelper elfLoadHelper,
ElfProgramHeader elfProgramHeader) {
Program program = elfLoadHelper.getProgram();
AddressSpace space =
getPreferredSegmentAddressSpace(elfLoadHelper, elfProgramHeader);
long addrWordOffset = elfProgramHeader.getVirtualAddress();
AddressSpace space = getPreferredSegmentAddressSpace(elfLoadHelper, elfProgramHeader);
if (space == program.getAddressFactory().getDefaultAddressSpace()) {
addrWordOffset += elfLoadHelper.getImageBaseWordAdjustmentOffset();
}
long addrWordOffset = elfProgramHeader.getVirtualAddress();
return space.getTruncatedAddress(addrWordOffset, true);
if (space == program.getAddressFactory().getDefaultAddressSpace()) {
addrWordOffset += elfLoadHelper.getImageBaseWordAdjustmentOffset();
}
return space.getTruncatedAddress(addrWordOffset, true);
}
/**
@@ -183,10 +180,11 @@ public class ElfLoadAdapter {
}
/**
* Get the preferred load address space for an allocated section.
* Get the preferred load address space for an allocated section. The OTHER space
* is reserved and should not be returned by this method.
* @param elfLoadHelper load helper object
* @param elfSectionHeader elf section header
* @return preferred load address space or null to use default behavior
* @return preferred load address space
*/
public AddressSpace getPreferredSectionAddressSpace(ElfLoadHelper elfLoadHelper,
ElfSectionHeader elfSectionHeader) {
@@ -197,9 +195,9 @@ public class ElfLoadAdapter {
// segment is not marked execute, use the data space by default
return program.getLanguage().getDefaultDataSpace();
}
/**
* Get the preferred load address for a program section
* Get the preferred load address for an allocated program section.
* @param elfLoadHelper load helper object
* @param elfSectionHeader elf program section header
* @return preferred load address
@@ -207,9 +205,9 @@ public class ElfLoadAdapter {
public Address getPreferredSectionAddress(ElfLoadHelper elfLoadHelper,
ElfSectionHeader elfSectionHeader) {
Program program = elfLoadHelper.getProgram();
AddressSpace space = getPreferredSectionAddressSpace(elfLoadHelper, elfSectionHeader);
long addrWordOffset = elfSectionHeader.getAddress();
if (space == program.getAddressFactory().getDefaultAddressSpace()) {
@@ -2158,6 +2158,19 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
return getDefaultAddressSpace().getTruncatedAddress(addressableWordOffset, true);
}
/**
* Get the preferred load address space for a program segment
* @param elfProgramHeader elf program segment header
* @return preferred load address space or null to use default behavior
*/
private AddressSpace getPreferredSegmentAddressSpace(ElfProgramHeader elfProgramHeader) {
if (elfProgramHeader.getType() != ElfProgramHeaderConstants.PT_LOAD &&
elfProgramHeader.getVirtualAddress() == 0) {
return AddressSpace.OTHER_SPACE;
}
return elf.getLoadAdapter().getPreferredSegmentAddressSpace(this, elfProgramHeader);
}
/**
* Determine segment preferred load address.
* While this method can produce the intended load address, there is no guarantee that
@@ -2165,10 +2178,14 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
* another segment or section.
* @param elfProgramHeader
* @return address or null if range check failed.
* @throws AddressOutOfBoundsException
*/
private Address getPreferredSegmentLoadAddress(ElfProgramHeader elfProgramHeader)
throws AddressOutOfBoundsException {
private Address getPreferredSegmentLoadAddress(ElfProgramHeader elfProgramHeader) {
AddressSpace space = getPreferredSegmentAddressSpace(elfProgramHeader);
if (!space.isLoadedMemorySpace()) {
// handle non-loaded sections into the OTHER space
long addrWordOffset = elfProgramHeader.getVirtualAddress();
return space.getTruncatedAddress(addrWordOffset, true);
}
return elf.getLoadAdapter().getPreferredSegmentAddress(this, elfProgramHeader);
}
@@ -2202,10 +2219,15 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
* Determine section's preferred load address
* @param elfSectionHeader
* @return preferred load address
* @throws AddressOutOfBoundsException
*/
private Address getPreferredSectionLoadAddress(ElfSectionHeader elfSectionHeader)
throws AddressOutOfBoundsException {
private Address getPreferredSectionLoadAddress(ElfSectionHeader elfSectionHeader) {
AddressSpace space = getPreferredSectionAddressSpace(elfSectionHeader);
if (!space.isLoadedMemorySpace()) {
// handle non-loaded sections into the OTHER space
long addrWordOffset = elfSectionHeader.getAddress();
return space.getTruncatedAddress(addrWordOffset, true);
}
return elf.getLoadAdapter().getPreferredSectionAddress(this, elfSectionHeader);
}
@@ -15,14 +15,7 @@
*/
package ghidra.app.util.bin.format.elf.extend;
import ghidra.app.util.bin.format.elf.ElfConstants;
import ghidra.app.util.bin.format.elf.ElfHeader;
import ghidra.app.util.bin.format.elf.ElfLoadHelper;
import ghidra.app.util.bin.format.elf.ElfProgramHeader;
import ghidra.app.util.bin.format.elf.ElfProgramHeaderType;
import ghidra.app.util.bin.format.elf.ElfSectionHeader;
import ghidra.app.util.bin.format.elf.ElfSectionHeaderType;
import ghidra.app.util.bin.format.elf.ElfSymbol;
import ghidra.app.util.bin.format.elf.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.Language;
@@ -54,105 +47,96 @@ public class HCS12X_ElfExtension extends ElfExtension {
public String getDataTypeSuffix() {
return "_HCS12";
}
@Override
public Address getPreferredSegmentAddress(ElfLoadHelper elfLoadHelper, ElfProgramHeader elfProgramHeader) {
AddressSpace space =
getPreferredSegmentAddressSpace(elfLoadHelper, elfProgramHeader);
if (space.equals(AddressSpace.OTHER_SPACE)) {
return space.getAddress(elfProgramHeader.getVirtualAddress());
}
public Address getPreferredSegmentAddress(ElfLoadHelper elfLoadHelper,
ElfProgramHeader elfProgramHeader) {
AddressSpace space = getPreferredSegmentAddressSpace(elfLoadHelper, elfProgramHeader);
Program program = elfLoadHelper.getProgram();
long addrWordOffset = elfProgramHeader.getVirtualAddress();
if (space == program.getAddressFactory().getDefaultAddressSpace()) {
addrWordOffset += elfLoadHelper.getImageBaseWordAdjustmentOffset();
}
addrWordOffset = hcs12TranslatePagedAddress(addrWordOffset);
return space.getTruncatedAddress(addrWordOffset, true);
}
@Override
public Address getPreferredSectionAddress(ElfLoadHelper elfLoadHelper,
ElfSectionHeader elfSectionHeader) {
// don't translate non-allocated sections
if (!elfSectionHeader.isAlloc()) {
return super.getPreferredSectionAddress(elfLoadHelper, elfSectionHeader);
}
Program program = elfLoadHelper.getProgram();
AddressSpace space = getPreferredSectionAddressSpace(elfLoadHelper, elfSectionHeader);
long addrWordOffset = elfSectionHeader.getAddress();
if (space == program.getAddressFactory().getDefaultAddressSpace()) {
addrWordOffset += elfLoadHelper.getImageBaseWordAdjustmentOffset();
}
addrWordOffset = hcs12TranslatePagedAddress(addrWordOffset);
return space.getTruncatedAddress(addrWordOffset, true);
}
private long hcs12TranslatePagedAddress(long addrWordOffset) {
long page = (addrWordOffset >> 16) & 0xff;
long addr = addrWordOffset & 0xffff;
// Register address
if ( (addr & 0xfC00) == 0x0) {
if ((addr & 0xfC00) == 0x0) {
return addr;
}
// EPage address
if ((addr & 0xfc00) ==0x800) {
return 0x100000 | ((page << 10) | (addr & 0x3ff));
if ((addr & 0xfc00) == 0x800) {
return 0x100000 | ((page << 10) | (addr & 0x3ff));
}
// EPage FF fixed address
if ((addr & 0xfc00) ==0xC00) {
if ((addr & 0xfc00) == 0xC00) {
return (0x4FF << 10) | (addr & 0x3ff);
}
// RPage address
if ((addr & 0xf000) ==0x1000) {
if ((addr & 0xf000) == 0x1000) {
return (page << 12) | (addr & 0xfff);
}
// RPage FE fixed address
if ((addr & 0xf000) ==0x2000) {
if ((addr & 0xf000) == 0x2000) {
return (0xFE << 12) | (addr & 0xfff);
}
// RPage FF fixed address
if ((addr & 0xf000) ==0x3000) {
if ((addr & 0xf000) == 0x3000) {
return (0xFF << 12) | (addr & 0xfff);
}
// PPage FD fixed address
if ((addr & 0xc000) ==0x4000) {
if ((addr & 0xc000) == 0x4000) {
return 0x400000 | (0xFD << 14) | (addr & 0x3fff);
}
// PPage address
if ((addr & 0xc000) ==0x8000) {
if ((addr & 0xc000) == 0x8000) {
return 0x400000 | (page << 14) | (addr & 0x3fff);
}
// PPage FF fixed address
if ((addr & 0xc000) ==0xC000) {
if ((addr & 0xc000) == 0xC000) {
return 0x400000 | (0xFF << 14) | (addr & 0x3fff);
}
return addr;
}
@@ -167,9 +151,9 @@ public class HCS12X_ElfExtension extends ElfExtension {
String symName = elfSymbol.getNameAsString();
long laddr = address.getOffset();
laddr = hcs12TranslatePagedAddress(laddr);
Address mappedAddr = address.getNewAddress(laddr);
return mappedAddr;