mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-24 13:05:55 +08:00
Corrected recently introduced ElfLoader bug causing non-loaded sections
to be improperly loaded into memory
This commit is contained in:
+20
-22
@@ -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);
|
||||
}
|
||||
|
||||
+36
-52
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user