mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 12:11:55 +00:00
GP-3260 Corrected MIPS relocation issues and a few related issues affecting listing markup
This commit is contained in:
parent
acb07dd535
commit
836604e09d
@ -472,7 +472,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
|
||||
/**
|
||||
* Processes the GNU version section.
|
||||
* @throws CancelledException
|
||||
* @throws CancelledException if load task is cancelled
|
||||
*/
|
||||
private void processGNU(TaskMonitor monitor) throws CancelledException {
|
||||
monitor.checkCanceled();
|
||||
@ -594,24 +594,6 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transition load segment to read-only
|
||||
* @param loadedSegment loaded segment
|
||||
*/
|
||||
private void setReadOnlyMemory(MemoryLoadable loadedSegment) {
|
||||
if (loadedSegment == null) {
|
||||
return;
|
||||
}
|
||||
List<AddressRange> resolvedLoadAddresses = getResolvedLoadAddresses(loadedSegment);
|
||||
if (resolvedLoadAddresses == null) {
|
||||
log("Set read-only failed for: " + loadedSegment + " (please report this issue)");
|
||||
return;
|
||||
}
|
||||
for (AddressRange range : resolvedLoadAddresses) {
|
||||
setReadOnlyMemory(range);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transition memory range to read-only
|
||||
* @param range constrained read-only region or null for entire load segment
|
||||
@ -670,7 +652,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
long entry = elf.e_entry(); // already adjusted for pre-link
|
||||
if (entry != 0) {
|
||||
Address entryAddr =
|
||||
createEntryFunction(ElfLoader.ELF_ENTRY_FUNCTION_NAME, entry, monitor);
|
||||
createEntryFunction(ElfLoader.ELF_ENTRY_FUNCTION_NAME, entry);
|
||||
if (entryAddr != null) {
|
||||
addElfHeaderReferenceMarkup(elf.getEntryComponentOrdinal(), entryAddr);
|
||||
}
|
||||
@ -703,7 +685,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
elf.adjustAddressForPrelink(dynamicTable.getDynamicValue(dynamicEntryType));
|
||||
if (entryArraySizeType == null) {
|
||||
// single entry addr case
|
||||
createEntryFunction("_" + dynamicEntryType.name, entryAddrOffset, monitor);
|
||||
createEntryFunction("_" + dynamicEntryType.name, entryAddrOffset);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -748,7 +730,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
funcAddr = getDefaultAddress(funcAddrOffset);
|
||||
data.addOperandReference(0, funcAddr, RefType.DATA, SourceType.ANALYSIS);
|
||||
}
|
||||
createEntryFunction(baseName + i, funcAddr, monitor);
|
||||
createEntryFunction(baseName + i, funcAddr);
|
||||
}
|
||||
}
|
||||
catch (NotFoundException e) {
|
||||
@ -763,13 +745,12 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
* @param name function name
|
||||
* @param entryAddr function address offset (must already be adjusted for pre-linking).
|
||||
* Any required image-base adjustment will be applied before converting to an Address.
|
||||
* @param monitor task monitor
|
||||
* @return address which corresponds to entryAddr
|
||||
*/
|
||||
private Address createEntryFunction(String name, long entryAddr, TaskMonitor monitor) {
|
||||
private Address createEntryFunction(String name, long entryAddr) {
|
||||
entryAddr += getImageBaseWordAdjustmentOffset(); // word offset
|
||||
Address entryAddress = getDefaultAddressSpace().getTruncatedAddress(entryAddr, true);
|
||||
createEntryFunction(name, entryAddress, monitor);
|
||||
createEntryFunction(name, entryAddress);
|
||||
return entryAddress;
|
||||
}
|
||||
|
||||
@ -778,9 +759,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
* Note: entries in the dynamic table appear to have any pre-link adjustment already applied.
|
||||
* @param name function name
|
||||
* @param entryAddress function Address
|
||||
* @param monitor task monitor
|
||||
*/
|
||||
private void createEntryFunction(String name, Address entryAddress, TaskMonitor monitor) {
|
||||
private void createEntryFunction(String name, Address entryAddress) {
|
||||
|
||||
// TODO: Entry may refer to a pointer - make sure we have execute permission
|
||||
|
||||
@ -1112,14 +1092,21 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
Address maxAddr = address.addNoWrap(length - 1);
|
||||
RelocationTable relocationTable = program.getRelocationTable();
|
||||
List<Relocation> relocations = relocationTable.getRelocations(address);
|
||||
if (!relocations.isEmpty()) {
|
||||
Msg.warn(this, "Artificial relocation at " + address +
|
||||
" conflicts with a previous relocation");
|
||||
boolean hasConflict = false;
|
||||
for (Relocation reloc : relocations) {
|
||||
if (reloc.getStatus() != Status.APPLIED_OTHER || reloc.getLength() != length) {
|
||||
hasConflict = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Address nextRelocAddr = relocationTable.getRelocationAddressAfter(address);
|
||||
if (nextRelocAddr != null && nextRelocAddr.compareTo(maxAddr) <= 0) {
|
||||
if (!hasConflict) {
|
||||
Address nextRelocAddr = relocationTable.getRelocationAddressAfter(address);
|
||||
hasConflict = nextRelocAddr != null && nextRelocAddr.compareTo(maxAddr) <= 0;
|
||||
}
|
||||
if (hasConflict) {
|
||||
Msg.warn(this,
|
||||
"Artificial relocation at " + address + " overlaps a previous relocation");
|
||||
"Artificial relocation for " + address +
|
||||
" conflicts with a previous relocation");
|
||||
}
|
||||
relocationTable.add(address, Status.APPLIED_OTHER, 0, null, length, null);
|
||||
return true;
|
||||
@ -1132,8 +1119,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
|
||||
/**
|
||||
* Add reference to previously applied header structure (assumes markupElfHeader previously called)
|
||||
* @param componentName
|
||||
* @param refAddr
|
||||
* @param componentOrdinal structure component ordinal
|
||||
* @param refAddr reference to-address
|
||||
*/
|
||||
private void addElfHeaderReferenceMarkup(int componentOrdinal, Address refAddr) {
|
||||
|
||||
@ -1355,10 +1342,6 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
return program.getLanguage().getDefaultDataSpace();
|
||||
}
|
||||
|
||||
private AddressSpace getConstantSpace() {
|
||||
return program.getAddressFactory().getConstantSpace();
|
||||
}
|
||||
|
||||
private void allocateUndefinedSymbolData(HashMap<Address, Integer> dataAllocationMap) {
|
||||
for (Address addr : dataAllocationMap.keySet()) {
|
||||
// Create undefined data for each data/object symbol
|
||||
@ -2673,8 +2656,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
|
||||
if (dynamicType != null) {
|
||||
if (dynamicType.valueType == ElfDynamicValueType.ADDRESS) {
|
||||
addDynamicMemoryReference(dynamics[i], valueData, false,
|
||||
"_" + dynamicType.name);
|
||||
addDynamicMemoryReference(valueData, false, "_" + dynamicType.name);
|
||||
}
|
||||
else if (dynamicType.valueType == ElfDynamicValueType.STRING) {
|
||||
ElfStringTable dynamicStringTable = elf.getDynamicStringTable();
|
||||
@ -2695,17 +2677,18 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add memory reference to dynamic table value and return the referenced address
|
||||
* Add memory reference to dynamic table scalar value and return the referenced address
|
||||
* specified by the value
|
||||
* @param elfDynamic
|
||||
* @param valueData
|
||||
* @param definedMemoryOnly
|
||||
* @param label
|
||||
* @return referenced address specified by the value
|
||||
* @throws InvalidInputException
|
||||
* @param valueData defined {@link Data} within the dynamic table whose operand value should
|
||||
* be treated as an address offset and to which a memory reference should be applied.
|
||||
* @param definedMemoryOnly if true derived reference to-address must exist within a defined
|
||||
* memory block.
|
||||
* @param label optional label to be applied at reference to-address (may be null)
|
||||
* @return referenced to-address specified by the value
|
||||
* @throws InvalidInputException if an invalid label name is specified
|
||||
*/
|
||||
private Address addDynamicMemoryReference(ElfDynamic elfDynamic, Data valueData,
|
||||
boolean definedMemoryOnly, String label) throws InvalidInputException {
|
||||
private Address addDynamicMemoryReference(Data valueData, boolean definedMemoryOnly,
|
||||
String label) throws InvalidInputException {
|
||||
Scalar value = valueData.getScalar(0);
|
||||
if (value == null || value.getUnsignedValue() == 0) {
|
||||
return null;
|
||||
@ -2836,7 +2819,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
* While this method can produce the intended load address, there is no guarantee that
|
||||
* the segment data did not get bumped into an overlay area due to a conflict with
|
||||
* another segment or section.
|
||||
* @param elfProgramHeader
|
||||
* @param elfProgramHeader ELF program header
|
||||
* @return segment load address
|
||||
*/
|
||||
private Address getSegmentLoadAddress(ElfProgramHeader elfProgramHeader) {
|
||||
@ -2854,7 +2837,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
* Determine preferred section load address address space prior to load.
|
||||
* Non-allocated sections may return the OTHER space or an existing OTHER
|
||||
* overlay established by a program header.
|
||||
* @param elfSectionHeader
|
||||
* @param elfSectionHeader ELF section header
|
||||
* @return section load address space
|
||||
*/
|
||||
private AddressSpace getSectionAddressSpace(ElfSectionHeader elfSectionHeader) {
|
||||
@ -2878,7 +2861,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
|
||||
/**
|
||||
* Determine section's load address.
|
||||
* @param elfSectionHeader
|
||||
* @param elfSectionHeader ELF section header
|
||||
* @return section load address
|
||||
*/
|
||||
private Address getSectionLoadAddress(ElfSectionHeader elfSectionHeader) {
|
||||
@ -3015,8 +2998,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
* Expand/create PT_LOAD program header block regions which are zeroed
|
||||
* - to the extent possible. This should only be done when section headers are
|
||||
* not present.
|
||||
* @param monitor
|
||||
* @throws CancelledException
|
||||
* @param monitor load task monitor
|
||||
* @throws CancelledException if load task is cancelled
|
||||
*/
|
||||
private void expandProgramHeaderBlocks(TaskMonitor monitor) throws CancelledException {
|
||||
|
||||
@ -3583,7 +3566,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
* @param fileOffset byte provider offset
|
||||
* @param dataLength the in-memory data length in bytes (actual bytes read from dataInput may be more)
|
||||
* @return input stream for loading memory block
|
||||
* @throws IOException
|
||||
* @throws IOException if failed to obtain input stream
|
||||
*/
|
||||
private InputStream getInitializedBlockInputStream(MemoryLoadable loadable, Address start,
|
||||
long fileOffset, long dataLength) throws IOException {
|
||||
|
@ -1202,10 +1202,9 @@ public class CodeUnitFormat {
|
||||
long offset = offsetRef.getOffset();
|
||||
String sign = "+";
|
||||
if (offset < 0) {
|
||||
offset = -offset;
|
||||
sign = "-";
|
||||
sign = ""; // sign provided by Scalar.toString()
|
||||
}
|
||||
Scalar offsetScalar = new Scalar(64, offsetRef.getOffset(), true);
|
||||
Scalar offsetScalar = new Scalar(64, offset, true);
|
||||
OperandRepresentationList list = new OperandRepresentationList();
|
||||
list.add(baseRefObj);
|
||||
list.add(sign);
|
||||
|
@ -2477,7 +2477,8 @@ public class SymbolicPropogator {
|
||||
}
|
||||
|
||||
private int createData(Address address, int size) {
|
||||
if (!program.getListing().isUndefined(address, address)) {
|
||||
if (program.getMemory().isExternalBlockAddress(address) ||
|
||||
!program.getListing().isUndefined(address, address)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,9 @@ public abstract class DecompilerReference {
|
||||
int n = parent.getLength();
|
||||
if (offset >= 0 && offset < n) {
|
||||
DataTypeComponent dtc = parent.getComponentContaining(field.getOffset());
|
||||
fieldDt = dtc.getDataType();
|
||||
if (dtc != null) {
|
||||
return dtc.getDataType();
|
||||
}
|
||||
}
|
||||
}
|
||||
return fieldDt;
|
||||
|
@ -18,6 +18,7 @@ package ghidra.program.database.references;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.NumericUtilities;
|
||||
|
||||
class OffsetReferenceDB extends MemReferenceDB implements OffsetReference {
|
||||
|
||||
@ -58,7 +59,8 @@ class OffsetReferenceDB extends MemReferenceDB implements OffsetReference {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " Offset: 0x" + Long.toHexString(offsetOrShift);
|
||||
String offsetStr = NumericUtilities.toSignedHexString(offsetOrShift);
|
||||
return super.toString() + " Offset: " + offsetStr;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -114,7 +114,12 @@ public class ComponentOffsetSettingsDefinition
|
||||
public String getAttributeSpecification(Settings settings) {
|
||||
if (hasValue(settings)) {
|
||||
long offset = getValue(settings);
|
||||
return "offset(0x" + Long.toHexString(offset) + ")";
|
||||
String sign = "";
|
||||
if (offset < 0) {
|
||||
offset = -offset;
|
||||
sign = "-";
|
||||
}
|
||||
return "offset(" + sign + "0x" + Long.toHexString(offset) + ")";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -184,6 +184,16 @@ public class Relocation {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of original instruction bytes affected by applied relocation.
|
||||
*
|
||||
* @return number of original instruction bytes affected by relocation if it was successfully applied
|
||||
* (i.e., {@link Status#APPLIED}, {@link Status#APPLIED_OTHER}), otherwise null may be returned.
|
||||
*/
|
||||
public int getLength() {
|
||||
return bytes != null ? bytes.length : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the symbol being relocated or <code>null</code> if there is no symbol name.
|
||||
*
|
||||
|
@ -16,6 +16,7 @@
|
||||
package ghidra.app.util.bin.format.elf.extend;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@ -460,7 +461,7 @@ public class MIPS_ElfExtension extends ElfExtension {
|
||||
|
||||
setTableEntryIfZero(gotBaseAddress, gotIndex, symbolOffset, elfLoadHelper);
|
||||
}
|
||||
catch (MemoryAccessException | AddressOverflowException e) {
|
||||
catch (MemoryAccessException e) {
|
||||
Msg.error(this, "Failed to update .got table entry", e);
|
||||
}
|
||||
catch (NotFoundException e) {
|
||||
@ -682,6 +683,14 @@ public class MIPS_ElfExtension extends ElfExtension {
|
||||
|
||||
// NOTES: assumes only one gp0 value
|
||||
|
||||
|
||||
AtomicBoolean multipleGp0 = new AtomicBoolean(false);
|
||||
Symbol gp0Sym = SymbolUtilities.getLabelOrFunctionSymbol(elfLoadHelper.getProgram(),
|
||||
MIPS_GP0_VALUE_SYMBOL, msg -> multipleGp0.set(true));
|
||||
Long otherGp0Value = gp0Sym != null ? gp0Sym.getAddress().getOffset() : null;
|
||||
|
||||
AddressSpace defaultSpace =
|
||||
elfLoadHelper.getProgram().getAddressFactory().getDefaultAddressSpace();
|
||||
boolean is64bit = elfLoadHelper.getElfHeader().is64Bit();
|
||||
Structure regInfoStruct = buildRegInfoStructure(is64bit);
|
||||
|
||||
@ -692,8 +701,15 @@ public class MIPS_ElfExtension extends ElfExtension {
|
||||
// Create gp0 symbol in default space which represents a constant value (pinned)
|
||||
Scalar gp0Value = gpValueComponent.getScalar(0);
|
||||
long gp0 = gp0Value.getUnsignedValue();
|
||||
AddressSpace defaultSpace =
|
||||
elfLoadHelper.getProgram().getAddressFactory().getDefaultAddressSpace();
|
||||
if (multipleGp0.get() || otherGp0Value != null) {
|
||||
if (multipleGp0.get() || gp0 != otherGp0Value) {
|
||||
elfLoadHelper.log(
|
||||
"Multiple gp0 values defined (not supported): 0x" +
|
||||
Long.toHexString(gp0));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Address gpAddr = defaultSpace.getAddress(gp0);
|
||||
elfLoadHelper.createSymbol(gpAddr, MIPS_GP0_VALUE_SYMBOL, false, false,
|
||||
null).setPinned(true);
|
||||
@ -870,9 +886,10 @@ public class MIPS_ElfExtension extends ElfExtension {
|
||||
tableEntryAddr = tableBaseAddr.add(entryIndex * 8);
|
||||
if (adjustment != 0) {
|
||||
long offset = memory.getLong(tableEntryAddr);
|
||||
if (offset != 0) {
|
||||
long newValue = offset + adjustment;
|
||||
if (offset != 0 && offset != newValue) {
|
||||
elfLoadHelper.addArtificialRelocTableEntry(tableEntryAddr, 8);
|
||||
memory.setLong(tableEntryAddr, offset + adjustment);
|
||||
memory.setLong(tableEntryAddr, newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -880,9 +897,10 @@ public class MIPS_ElfExtension extends ElfExtension {
|
||||
tableEntryAddr = tableBaseAddr.add(entryIndex * 4);
|
||||
if (adjustment != 0) {
|
||||
int offset = memory.getInt(tableEntryAddr);
|
||||
if (offset != 0) {
|
||||
int newValue = (int) (offset + adjustment);
|
||||
if (offset != 0 && offset != newValue) {
|
||||
elfLoadHelper.addArtificialRelocTableEntry(tableEntryAddr, 4);
|
||||
memory.setInt(tableEntryAddr, (int) (offset + adjustment));
|
||||
memory.setInt(tableEntryAddr, newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -890,14 +908,14 @@ public class MIPS_ElfExtension extends ElfExtension {
|
||||
}
|
||||
|
||||
private Address setTableEntryIfZero(Address tableBaseAddr, int entryIndex, long value,
|
||||
ElfLoadHelper elfLoadHelper) throws MemoryAccessException, AddressOverflowException {
|
||||
ElfLoadHelper elfLoadHelper) throws MemoryAccessException {
|
||||
boolean is64Bit = elfLoadHelper.getElfHeader().is64Bit();
|
||||
Memory memory = elfLoadHelper.getProgram().getMemory();
|
||||
Address tableEntryAddr;
|
||||
if (is64Bit) {
|
||||
tableEntryAddr = tableBaseAddr.add(entryIndex * 8);
|
||||
long offset = memory.getLong(tableEntryAddr);
|
||||
if (offset == 0) {
|
||||
if (offset == 0 && value != 0) {
|
||||
elfLoadHelper.addArtificialRelocTableEntry(tableEntryAddr, 8);
|
||||
memory.setLong(tableEntryAddr, value);
|
||||
}
|
||||
@ -905,7 +923,7 @@ public class MIPS_ElfExtension extends ElfExtension {
|
||||
else {
|
||||
tableEntryAddr = tableBaseAddr.add(entryIndex * 4);
|
||||
int offset = memory.getInt(tableEntryAddr);
|
||||
if (offset == 0) {
|
||||
if (offset == 0 && value != 0) {
|
||||
elfLoadHelper.addArtificialRelocTableEntry(tableEntryAddr, 4);
|
||||
memory.setInt(tableEntryAddr, (int) value);
|
||||
}
|
||||
|
@ -63,7 +63,8 @@ public class MIPS_Elf64Relocation extends ElfRelocation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the special symbol index associated with this relocation
|
||||
* Return the special symbol index associated with this relocation. This symbol
|
||||
* may be used by the 2nd relocation of a compound relocations.
|
||||
* @return special symbol index (r_ssym)
|
||||
*/
|
||||
public int getSpecialSymbolIndex() {
|
||||
|
@ -75,6 +75,14 @@ public class MIPS_ElfRelocationConstants {
|
||||
public static final int R_MIPS_TLS_TPREL_LO16 = 50;
|
||||
public static final int R_MIPS_GLOB_DAT = 51;
|
||||
|
||||
/* MIPSr6 relocations */
|
||||
public static final int R_MIPS_PC21_S2 = 60;
|
||||
public static final int R_MIPS_PC26_S2 = 61;
|
||||
public static final int R_MIPS_PC18_S3 = 62;
|
||||
public static final int R_MIPS_PC19_S2 = 63;
|
||||
public static final int R_MIPS_PCHI16 = 64;
|
||||
public static final int R_MIPS_PCLO16 = 65;
|
||||
|
||||
/* These relocs are used for the mips16. */
|
||||
public static final int R_MIPS16_26 = 100;
|
||||
public static final int R_MIPS16_GPREL = 101;
|
||||
@ -144,6 +152,7 @@ public class MIPS_ElfRelocationConstants {
|
||||
|
||||
// Masks for manipulating MIPS relocation targets
|
||||
public static final int MIPS_LOW26 = 0x03FFFFFF;
|
||||
public static final int MIPS_LOW21 = 0x001FFFFF;
|
||||
|
||||
private MIPS_ElfRelocationConstants() {
|
||||
// no construct
|
||||
|
@ -51,6 +51,7 @@ class MIPS_ElfRelocationContext extends ElfRelocationContext {
|
||||
boolean savedAddendHasError = false;
|
||||
long savedAddend;
|
||||
|
||||
ElfSymbol lastElfSymbol;
|
||||
Address lastSymbolAddr;
|
||||
|
||||
MIPS_ElfRelocationContext(MIPS_ElfRelocationHandler handler, ElfLoadHelper loadHelper,
|
||||
@ -82,6 +83,7 @@ class MIPS_ElfRelocationContext extends ElfRelocationContext {
|
||||
useSavedAddend = false;
|
||||
savedAddendHasError = false;
|
||||
lastSymbolAddr = null;
|
||||
lastElfSymbol = null;
|
||||
|
||||
super.endRelocationTableProcessing();
|
||||
}
|
||||
|
@ -15,19 +15,19 @@
|
||||
*/
|
||||
package ghidra.app.util.bin.format.elf.relocation;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import ghidra.app.util.bin.format.elf.*;
|
||||
import ghidra.app.util.bin.format.elf.extend.MIPS_ElfExtension;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressOutOfBoundsException;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.*;
|
||||
import ghidra.program.model.reloc.Relocation.Status;
|
||||
import ghidra.program.model.reloc.RelocationResult;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.NotFoundException;
|
||||
|
||||
public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
|
||||
@ -47,8 +47,8 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
|
||||
@Override
|
||||
public RelocationResult relocate(ElfRelocationContext elfRelocationContext,
|
||||
ElfRelocation relocation,
|
||||
Address relocationAddress) throws MemoryAccessException, NotFoundException {
|
||||
ElfRelocation relocation, Address relocationAddress)
|
||||
throws MemoryAccessException {
|
||||
|
||||
ElfHeader elf = elfRelocationContext.getElfHeader();
|
||||
|
||||
@ -59,6 +59,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
MIPS_ElfRelocationContext mipsRelocationContext =
|
||||
(MIPS_ElfRelocationContext) elfRelocationContext;
|
||||
mipsRelocationContext.lastSymbolAddr = null;
|
||||
mipsRelocationContext.lastElfSymbol = null;
|
||||
|
||||
int type = relocation.getType();
|
||||
int symbolIndex = relocation.getSymbolIndex();
|
||||
@ -68,17 +69,30 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
|
||||
RelocationResult lastResult = RelocationResult.FAILURE;
|
||||
if (elf.is64Bit()) {
|
||||
|
||||
MIPS_Elf64Relocation mips64Relocation = (MIPS_Elf64Relocation) relocation;
|
||||
|
||||
// Each relocation can pack upto 3 relocations for 64-bit
|
||||
for (int n = 0; n < 3; n++) {
|
||||
|
||||
if (n == 0) {
|
||||
symbolIndex = mips64Relocation.getSymbolIndex();
|
||||
}
|
||||
else if (n == 1) {
|
||||
symbolIndex = mips64Relocation.getSpecialSymbolIndex();
|
||||
}
|
||||
else {
|
||||
symbolIndex = 0;
|
||||
}
|
||||
|
||||
int relocType = type & 0xff;
|
||||
type >>= 8;
|
||||
int nextRelocType =
|
||||
(n < 2) ? (type & 0xff) : MIPS_ElfRelocationConstants.R_MIPS_NONE;
|
||||
|
||||
RelocationResult result = doRelocate(mipsRelocationContext, relocType, symbolIndex,
|
||||
relocation,
|
||||
relocationAddress, nextRelocType != MIPS_ElfRelocationConstants.R_MIPS_NONE ||
|
||||
mips64Relocation, relocationAddress,
|
||||
nextRelocType != MIPS_ElfRelocationConstants.R_MIPS_NONE ||
|
||||
saveValueForNextReloc);
|
||||
if (result.status() == Status.FAILURE || result.status() == Status.UNSUPPORTED) {
|
||||
return result;
|
||||
@ -102,19 +116,17 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
* Perform MIPS ELF relocation
|
||||
* @param mipsRelocationContext MIPS ELF relocation context
|
||||
* @param relocType relocation type (unpacked from relocation r_info)
|
||||
* @param relocation
|
||||
* @param relocation relocation record to be processed (may be compound for 64-bit)
|
||||
* @param relocationAddress address at which relocation is applied (i.e., relocation offset)
|
||||
* @param saveValue true if result value should be stored in mipsRelocationContext.savedAddend
|
||||
* and mipsRelocationContext.useSavedAddend set true. If false, result value should be written
|
||||
* to relocationAddress per relocation type.
|
||||
* @return applied relocation result
|
||||
* @throws MemoryAccessException
|
||||
* @throws NotFoundException
|
||||
* @throws MemoryAccessException memory access error occured
|
||||
*/
|
||||
private RelocationResult doRelocate(MIPS_ElfRelocationContext mipsRelocationContext,
|
||||
int relocType,
|
||||
int symbolIndex, ElfRelocation relocation, Address relocationAddress, boolean saveValue)
|
||||
throws MemoryAccessException, NotFoundException, AddressOutOfBoundsException {
|
||||
int relocType, int symbolIndex, ElfRelocation relocation, Address relocationAddress,
|
||||
boolean saveValue) throws MemoryAccessException, AddressOutOfBoundsException {
|
||||
|
||||
if (relocType == MIPS_ElfRelocationConstants.R_MIPS_NONE) {
|
||||
return RelocationResult.SKIPPED;
|
||||
@ -137,6 +149,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
|
||||
if (symbolIndex != 0) {
|
||||
mipsRelocationContext.lastSymbolAddr = symbolAddr;
|
||||
mipsRelocationContext.lastElfSymbol = elfSymbol;
|
||||
}
|
||||
|
||||
long addend = 0;
|
||||
@ -184,10 +197,14 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
return RelocationResult.FAILURE;
|
||||
}
|
||||
|
||||
int oldValue =
|
||||
unshuffle(memory.getInt(relocationAddress), relocType, mipsRelocationContext);
|
||||
int value = 0; // computed value which will be used as savedAddend if needed
|
||||
int newValue = 0; // value blended with oldValue as appropriate for relocation
|
||||
long oldValue = Integer.toUnsignedLong(
|
||||
unshuffle(memory.getInt(relocationAddress), relocType, mipsRelocationContext));
|
||||
|
||||
// Intermediate results are retained as long values so they may be used with 64-bit
|
||||
// compound relocation processing
|
||||
|
||||
long value = 0; // computed value which will be used as savedAddend if needed
|
||||
long newValue = 0; // value blended with oldValue as appropriate for relocation
|
||||
boolean writeNewValue = false;
|
||||
|
||||
Status status = Status.PARTIAL;
|
||||
@ -202,7 +219,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
}
|
||||
|
||||
long pageOffset = (symbolValue + addend + 0x8000) & ~0xffff;
|
||||
value = (int) (symbolValue + addend - pageOffset);
|
||||
value = symbolValue + addend - pageOffset;
|
||||
|
||||
newValue = (oldValue & ~0xffff) | (value & 0xffff);
|
||||
writeNewValue = true;
|
||||
@ -229,7 +246,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
return RelocationResult.FAILURE;
|
||||
}
|
||||
|
||||
value = (int) getGpOffset(mipsRelocationContext, gotAddr.getOffset());
|
||||
value = getGpOffset(mipsRelocationContext, gotAddr.getOffset());
|
||||
if (value == -1) {
|
||||
// Unhandled GOT/GP case
|
||||
markAsError(mipsRelocationContext.getProgram(), relocationAddress,
|
||||
@ -263,7 +280,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
}
|
||||
|
||||
// use address offset within section GOT as symbol value
|
||||
value = (int) getGpOffset(mipsRelocationContext, gotAddr.getOffset());
|
||||
value = getGpOffset(mipsRelocationContext, gotAddr.getOffset());
|
||||
if (value == -1) {
|
||||
// Unhandled GOT/GP case
|
||||
markAsError(mipsRelocationContext.getProgram(), relocationAddress,
|
||||
@ -275,7 +292,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
return RelocationResult.FAILURE;
|
||||
}
|
||||
|
||||
int appliedValue;
|
||||
long appliedValue;
|
||||
if (relocType == MIPS_ElfRelocationConstants.R_MIPS_GOT_DISP) {
|
||||
appliedValue = value & 0xffff;
|
||||
}
|
||||
@ -294,7 +311,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
if (elfSymbol.isLocal()) {
|
||||
// Defer processing of local GOT16 relocations until suitable LO16 relocation is processed
|
||||
MIPS_DeferredRelocation got16reloc = new MIPS_DeferredRelocation(relocType,
|
||||
elfSymbol, relocationAddress, oldValue, (int) addend, isGpDisp);
|
||||
elfSymbol, relocationAddress, oldValue, addend, isGpDisp);
|
||||
mipsRelocationContext.addGOT16Relocation(got16reloc);
|
||||
break; // report as 4-byte applied even though it is deferred (could still fail)
|
||||
}
|
||||
@ -317,7 +334,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
return RelocationResult.FAILURE;
|
||||
}
|
||||
|
||||
value = (int) getGpOffset(mipsRelocationContext, gotAddr.getOffset());
|
||||
value = getGpOffset(mipsRelocationContext, gotAddr.getOffset());
|
||||
if (value == -1) {
|
||||
// Unhandled GOT/GP case
|
||||
markAsError(mipsRelocationContext.getProgram(), relocationAddress,
|
||||
@ -348,7 +365,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
return RelocationResult.FAILURE;
|
||||
}
|
||||
|
||||
value = (int) getGpOffset(mipsRelocationContext, gotAddr.getOffset());
|
||||
value = getGpOffset(mipsRelocationContext, gotAddr.getOffset());
|
||||
if (value == -1) {
|
||||
// Unhandled GOT/GP case
|
||||
markAsError(mipsRelocationContext.getProgram(), relocationAddress,
|
||||
@ -395,7 +412,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
processGOT16Relocations(mipsRelocationContext, relocType, elfSymbol, (int) addend);
|
||||
|
||||
if (isGpDisp) {
|
||||
value = (int) mipsRelocationContext.getGPValue();
|
||||
value = mipsRelocationContext.getGPValue();
|
||||
if (value == -1) {
|
||||
markAsError(program, relocationAddress, Integer.toString(relocType),
|
||||
symbolName, "Failed to perform GP-based relocation",
|
||||
@ -422,43 +439,48 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
break;
|
||||
|
||||
case MIPS_ElfRelocationConstants.R_MIPS_REL32:
|
||||
// TODO: unsure if reloc valid for symbolIndex != 0
|
||||
if (symbolIndex == 0) {
|
||||
symbolValue = mipsRelocationContext.getImageBaseWordAdjustmentOffset();
|
||||
}
|
||||
case MIPS_ElfRelocationConstants.R_MIPS_32:
|
||||
value = (int) symbolValue;
|
||||
int intAddend;
|
||||
value = symbolValue;
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
intAddend = elf.is64Bit() ? (int) memory.getLong(relocationAddress)
|
||||
// extract addend based upon pointer size
|
||||
addend = elf.is64Bit() ? (int) memory.getLong(relocationAddress)
|
||||
: memory.getInt(relocationAddress);
|
||||
}
|
||||
else {
|
||||
intAddend = (int) addend;
|
||||
}
|
||||
|
||||
newValue = value + intAddend;
|
||||
long newValueBig = Integer.toUnsignedLong(newValue);
|
||||
newValue = value + addend;
|
||||
|
||||
if (saveValue) {
|
||||
mipsRelocationContext.savedAddend = newValueBig;
|
||||
mipsRelocationContext.savedAddend = newValue;
|
||||
}
|
||||
else {
|
||||
if (elf.is64Bit()) {
|
||||
memory.setLong(relocationAddress, newValueBig);
|
||||
byteLength = 8;
|
||||
}
|
||||
else {
|
||||
memory.setInt(relocationAddress, newValue);
|
||||
byteLength = 4;
|
||||
}
|
||||
if (symbolIndex != 0 && intAddend != 0 && !saveValue) {
|
||||
// If not continuing with compound relocation (64-bit only)
|
||||
// perform fixup so we can create offset-pointer now.
|
||||
memory.setInt(relocationAddress, (int) newValue);
|
||||
status = Status.APPLIED;
|
||||
|
||||
// Handle possible offset-pointer use
|
||||
if (symbolIndex != 0 && addend != 0 && elfSymbol.isGlobal()) {
|
||||
// create offset-pointer and resulting offset-reference
|
||||
warnExternalOffsetRelocation(program, relocationAddress,
|
||||
symbolAddr, symbolName, intAddend, mipsRelocationContext.getLog());
|
||||
applyComponentOffsetPointer(program, relocationAddress, intAddend);
|
||||
symbolAddr, symbolName, addend, mipsRelocationContext.getLog());
|
||||
applyComponentOffsetPointer(program, relocationAddress, addend);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MIPS_ElfRelocationConstants.R_MIPS_32: /* In Elf 64: alias R_MIPS_ADD */
|
||||
value = symbolValue;
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = memory.getInt(relocationAddress);
|
||||
}
|
||||
|
||||
newValue = value + addend;
|
||||
|
||||
if (saveValue) {
|
||||
mipsRelocationContext.savedAddend = newValue;
|
||||
}
|
||||
else {
|
||||
memory.setInt(relocationAddress, (int) newValue);
|
||||
status = Status.APPLIED;
|
||||
}
|
||||
break;
|
||||
@ -474,20 +496,44 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
addend = signExtend((int) addend, 26 + shift);
|
||||
}
|
||||
// TODO: cross-mode jump detection/handling is unsupported
|
||||
value = (int) (addend + symbolValue) >> shift;
|
||||
value = (addend + symbolValue) >> shift;
|
||||
newValue = (oldValue & ~MIPS_ElfRelocationConstants.MIPS_LOW26) |
|
||||
(value & MIPS_ElfRelocationConstants.MIPS_LOW26);
|
||||
writeNewValue = true;
|
||||
break;
|
||||
|
||||
case MIPS_ElfRelocationConstants.R_MIPS_PC21_S2:
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = (oldValue & MIPS_ElfRelocationConstants.MIPS_LOW21) << 2;
|
||||
}
|
||||
if (!elfSymbol.isLocal() && !elfSymbol.isSection()) {
|
||||
addend = signExtend((int) addend, 21 + 2);
|
||||
}
|
||||
value = (addend + symbolValue - offset) >> 2;
|
||||
newValue = (oldValue & ~MIPS_ElfRelocationConstants.MIPS_LOW21) |
|
||||
(value & MIPS_ElfRelocationConstants.MIPS_LOW21);
|
||||
writeNewValue = true;
|
||||
break;
|
||||
|
||||
case MIPS_ElfRelocationConstants.R_MIPS_PC26_S2:
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = (oldValue & MIPS_ElfRelocationConstants.MIPS_LOW26) << 2;
|
||||
}
|
||||
if (!elfSymbol.isLocal() && !elfSymbol.isSection()) {
|
||||
addend = signExtend((int) addend, 26 + 2);
|
||||
}
|
||||
value = (addend + symbolValue - offset) >> 2;
|
||||
newValue = (oldValue & ~MIPS_ElfRelocationConstants.MIPS_LOW26) |
|
||||
(value & MIPS_ElfRelocationConstants.MIPS_LOW26);
|
||||
writeNewValue = true;
|
||||
break;
|
||||
|
||||
case MIPS_ElfRelocationConstants.R_MIPS_PC16:
|
||||
newValue =
|
||||
mipsRelocationContext.extractAddend() ? (oldValue & 0xffff) << 2 : (int) addend;
|
||||
newValueBig = signExtend(newValue, 18);
|
||||
newValueBig += symbolValue - offset;
|
||||
|
||||
value = (int) newValueBig;
|
||||
newValue = (oldValue & ~0xffff) | ((int) (newValueBig >> 2) & 0xffff);
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = (oldValue & 0xffff) << 2;
|
||||
}
|
||||
value = symbolValue - offset + signExtend((int) addend, 18);
|
||||
newValue = (oldValue & ~0xffff) | ((value >> 2) & 0xffff);
|
||||
writeNewValue = true;
|
||||
break;
|
||||
|
||||
@ -495,25 +541,31 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = memory.getLong(relocationAddress);
|
||||
}
|
||||
// NOTE: provisions may be needed for sign-extending a 32-bit value
|
||||
newValueBig = symbolValue + addend;
|
||||
newValue = symbolValue + addend;
|
||||
if (saveValue) {
|
||||
mipsRelocationContext.savedAddend = newValueBig;
|
||||
mipsRelocationContext.savedAddend = newValue;
|
||||
}
|
||||
else {
|
||||
memory.setLong(relocationAddress, newValueBig);
|
||||
memory.setLong(relocationAddress, newValue);
|
||||
byteLength = 8;
|
||||
status = Status.APPLIED;
|
||||
Address addr =
|
||||
symbolIndex == 0 ? mipsRelocationContext.lastSymbolAddr : symbolAddr;
|
||||
if (addr != null && addend != 0) {
|
||||
|
||||
// Handle possible offset-pointer use
|
||||
boolean isGlobal = elfSymbol.isGlobal();
|
||||
Address addr = symbolAddr;
|
||||
if (symbolIndex == 0 && mipsRelocationContext.lastSymbolAddr != null) {
|
||||
// handle compound mips64 relocation
|
||||
addr = mipsRelocationContext.lastSymbolAddr;
|
||||
symbolName = mipsRelocationContext.lastElfSymbol.getNameAsString();
|
||||
isGlobal = mipsRelocationContext.lastElfSymbol.isGlobal();
|
||||
}
|
||||
if (addr != null && isGlobal) {
|
||||
if (symbolIndex == 0) {
|
||||
// compute addend used with compound relocation and lastSymbolAddr
|
||||
addend -= addr.getOffset();
|
||||
}
|
||||
if (addend != 0) {
|
||||
// If not continuing with compound relocation perform fixup so
|
||||
// we can create offset-pointer now.
|
||||
// NOTE: this may not handle all combound relocation cases
|
||||
// create offset-pointer and resulting offset-reference
|
||||
warnExternalOffsetRelocation(program, relocationAddress,
|
||||
addr, symbolName, addend, mipsRelocationContext.getLog());
|
||||
if (elf.is64Bit()) {
|
||||
@ -526,83 +578,33 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
|
||||
case MIPS_ElfRelocationConstants.R_MIPS_HIGHER:
|
||||
case MIPS_ElfRelocationConstants.R_MICROMIPS_HIGHER:
|
||||
newValueBig = (mipsRelocationContext.extractAddend() ? oldValue : addend) & 0xffff;
|
||||
newValueBig += symbolValue + 0x080008000L;
|
||||
value = (int) ((newValueBig >> 32) & 0xffff);
|
||||
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = oldValue;
|
||||
}
|
||||
addend &= 0xffff;
|
||||
value = symbolValue + 0x080008000L + addend;
|
||||
value = (value >> 32) & 0xffff;
|
||||
newValue = (oldValue & ~0xffff) | value;
|
||||
writeNewValue = true;
|
||||
break;
|
||||
|
||||
case MIPS_ElfRelocationConstants.R_MIPS_HIGHEST:
|
||||
case MIPS_ElfRelocationConstants.R_MICROMIPS_HIGHEST:
|
||||
newValueBig = (mipsRelocationContext.extractAddend() ? oldValue : addend) & 0xffff;
|
||||
newValueBig += symbolValue + 0x0800080008000L;
|
||||
value = (int) ((newValueBig >> 48) & 0xffff);
|
||||
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = oldValue;
|
||||
}
|
||||
addend &= 0xffff;
|
||||
value = symbolValue + 0x080008000L + addend;
|
||||
value = (value >> 48) & 0xffff;
|
||||
newValue = (oldValue & ~0xffff) | value;
|
||||
writeNewValue = true;
|
||||
break;
|
||||
|
||||
// case MIPS_ElfRelocationConstants.R_MIPS_TLS_TPREL32:
|
||||
// if (mipsRelocationContext.extractAddend()) {
|
||||
// addend = oldValue;
|
||||
// }
|
||||
// value = (int) ((symbolValue + addend) - TP_OFFSET);
|
||||
//
|
||||
// newValue = value;
|
||||
// writeNewValue = true;
|
||||
// break;
|
||||
//
|
||||
// case MIPS_ElfRelocationConstants.R_MIPS_TLS_TPREL64:
|
||||
// if (mipsRelocationContext.extractAddend()) {
|
||||
// addend = oldValue;
|
||||
// }
|
||||
// newValueBig = symbolValue + addend - TP_OFFSET;
|
||||
//
|
||||
// if (saveValue) {
|
||||
// mipsRelocationContext.savedAddend = newValueBig;
|
||||
// }
|
||||
// else {
|
||||
// memory.setLong(relocationAddress, newValueBig);
|
||||
// byteLength = 8;
|
||||
// status = Status.APPLIED;
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// case MIPS_ElfRelocationConstants.R_MIPS_TLS_DTPREL32:
|
||||
// if (mipsRelocationContext.extractAddend()) {
|
||||
// addend = oldValue;
|
||||
// }
|
||||
// value = (int) ((symbolValue + addend) - DTP_OFFSET);
|
||||
//
|
||||
// newValue = value;
|
||||
// writeNewValue = true;
|
||||
// break;
|
||||
//
|
||||
//
|
||||
// case MIPS_ElfRelocationConstants.R_MIPS_TLS_DTPREL64:
|
||||
// if (mipsRelocationContext.extractAddend()) {
|
||||
// addend = oldValue;
|
||||
// }
|
||||
// newValueBig = symbolValue + addend - DTP_OFFSET;
|
||||
//
|
||||
// if (saveValue) {
|
||||
// mipsRelocationContext.savedAddend = newValueBig;
|
||||
// }
|
||||
// else {
|
||||
// memory.setLong(relocationAddress, newValueBig);
|
||||
// byteLength = 8;
|
||||
// status = Status.APPLIED;
|
||||
// }
|
||||
// break;
|
||||
|
||||
case MIPS_ElfRelocationConstants.R_MICROMIPS_PC7_S1:
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = (oldValue & 0x7f0000) >> 15;
|
||||
}
|
||||
value = (int) (((symbolValue + addend) - offset) >> 1) & 0x7f;
|
||||
|
||||
value = (((symbolValue + addend) - offset) >> 1) & 0x7f;
|
||||
newValue = (oldValue & ~0x7f0000) | (value << 16);
|
||||
writeNewValue = true;
|
||||
break;
|
||||
@ -611,8 +613,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = (oldValue & 0x3ff0000) >> 15;
|
||||
}
|
||||
value = (int) (((symbolValue + addend) - offset) >> 1) & 0x3ff;
|
||||
|
||||
value = (((symbolValue + addend) - offset) >> 1) & 0x3ff;
|
||||
newValue = (oldValue & ~0x3ff0000) | (value << 16);
|
||||
writeNewValue = true;
|
||||
break;
|
||||
@ -621,8 +622,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = (oldValue & 0xffff) << 1;
|
||||
}
|
||||
value = (int) (((symbolValue + addend) - offset) >> 1) & 0xffff;
|
||||
|
||||
value = (((symbolValue + addend) - offset) >> 1) & 0xffff;
|
||||
newValue = (oldValue & ~0xffff) | value;
|
||||
writeNewValue = true;
|
||||
break;
|
||||
@ -678,12 +678,11 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
return RelocationResult.FAILURE;
|
||||
}
|
||||
|
||||
value = (int) (symbolValue + addend - gp + gp0);
|
||||
value = (symbolValue + addend - gp + gp0);
|
||||
|
||||
int mask =
|
||||
relocType == MIPS_ElfRelocationConstants.R_MIPS_GPREL32 ? 0xffffffff : 0xffff;
|
||||
long mask =
|
||||
relocType == MIPS_ElfRelocationConstants.R_MIPS_GPREL32 ? 0xffffffffL : 0xffff;
|
||||
newValue = (oldValue & ~mask) | (value & mask);
|
||||
|
||||
writeNewValue = true;
|
||||
break;
|
||||
|
||||
@ -692,13 +691,13 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = oldValue;
|
||||
}
|
||||
newValueBig = symbolValue - addend;
|
||||
newValue = symbolValue - addend;
|
||||
|
||||
if (saveValue) {
|
||||
mipsRelocationContext.savedAddend = newValueBig;
|
||||
mipsRelocationContext.savedAddend = newValue;
|
||||
}
|
||||
else {
|
||||
memory.setLong(relocationAddress, newValueBig);
|
||||
memory.setLong(relocationAddress, newValue);
|
||||
byteLength = 8;
|
||||
status = Status.APPLIED;
|
||||
}
|
||||
@ -796,7 +795,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
// Each relocation which sets writeNewValue must establish a 32-bit newValue
|
||||
// to be written to relocationAddress.
|
||||
memory.setInt(relocationAddress,
|
||||
shuffle(newValue, relocType, mipsRelocationContext));
|
||||
shuffle((int) newValue, relocType, mipsRelocationContext));
|
||||
status = Status.APPLIED;
|
||||
}
|
||||
}
|
||||
@ -937,9 +936,9 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
* @return true if successful or false if unsupported
|
||||
*/
|
||||
private void processHI16Relocation(MIPS_ElfRelocationContext mipsRelocationContext,
|
||||
MIPS_DeferredRelocation hi16reloc, int lo16Addend) {
|
||||
MIPS_DeferredRelocation hi16reloc, long lo16Addend) {
|
||||
|
||||
int newValue;
|
||||
long newValue;
|
||||
if (hi16reloc.isGpDisp) {
|
||||
|
||||
newValue = (int) mipsRelocationContext.getGPValue();
|
||||
@ -960,20 +959,20 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
newValue = (int) mipsRelocationContext.getSymbolValue(hi16reloc.elfSymbol);
|
||||
}
|
||||
// FIXME: should always use hi16reloc.addend - figure out at time of deferral
|
||||
int addend;
|
||||
long addend;
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = ((hi16reloc.oldValue & 0xffff) << 16) + lo16Addend;
|
||||
addend = ((hi16reloc.oldValueL & 0xffff) << 16) + lo16Addend;
|
||||
}
|
||||
else {
|
||||
addend = hi16reloc.addend;
|
||||
addend = hi16reloc.addendL;
|
||||
}
|
||||
|
||||
newValue = (newValue + addend + 0x8000) >> 16;
|
||||
newValue = (hi16reloc.oldValue & ~0xffff) | (newValue & 0xffff);
|
||||
newValue = (hi16reloc.oldValueL & ~0xffff) | (newValue & 0xffff);
|
||||
Memory memory = mipsRelocationContext.getProgram().getMemory();
|
||||
try {
|
||||
memory.setInt(hi16reloc.relocAddr,
|
||||
shuffle(newValue, hi16reloc.relocType, mipsRelocationContext));
|
||||
shuffle((int) newValue, hi16reloc.relocType, mipsRelocationContext));
|
||||
}
|
||||
catch (MemoryAccessException e) {
|
||||
// Unexpected since we did a previous getInt without failure
|
||||
@ -1011,14 +1010,14 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
* @return true if successful or false if unsupported
|
||||
*/
|
||||
private void processGOT16Relocation(MIPS_ElfRelocationContext mipsRelocationContext,
|
||||
MIPS_DeferredRelocation got16reloc, int lo16Addend) {
|
||||
MIPS_DeferredRelocation got16reloc, long lo16Addend) {
|
||||
|
||||
long addend;
|
||||
if (mipsRelocationContext.extractAddend()) {
|
||||
addend = ((got16reloc.oldValue & 0xffff) << 16) + lo16Addend;
|
||||
addend = ((got16reloc.oldValueL & 0xffff) << 16) + lo16Addend;
|
||||
}
|
||||
else {
|
||||
addend = got16reloc.addend;
|
||||
addend = got16reloc.addendL;
|
||||
}
|
||||
|
||||
long symbolValue = (int) mipsRelocationContext.getSymbolValue(got16reloc.elfSymbol);
|
||||
@ -1047,12 +1046,12 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
int newValue = (got16reloc.oldValue & ~0xffff) | ((int) value & 0xffff);
|
||||
long newValue = (got16reloc.oldValueL & ~0xffff) | ((int) value & 0xffff);
|
||||
|
||||
Memory memory = mipsRelocationContext.getProgram().getMemory();
|
||||
try {
|
||||
memory.setInt(got16reloc.relocAddr,
|
||||
shuffle(newValue, got16reloc.relocType, mipsRelocationContext));
|
||||
shuffle((int) newValue, got16reloc.relocType, mipsRelocationContext));
|
||||
}
|
||||
catch (MemoryAccessException e) {
|
||||
// Unexpected since we did a previous getInt without failure
|
||||
@ -1079,17 +1078,17 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
final int relocType;
|
||||
final ElfSymbol elfSymbol;
|
||||
final Address relocAddr;
|
||||
final int oldValue;
|
||||
final int addend;
|
||||
final long oldValueL;
|
||||
final long addendL;
|
||||
final boolean isGpDisp;
|
||||
|
||||
MIPS_DeferredRelocation(int relocType, ElfSymbol elfSymbol, Address relocAddr, int oldValue,
|
||||
int addend, boolean isGpDisp) {
|
||||
MIPS_DeferredRelocation(int relocType, ElfSymbol elfSymbol, Address relocAddr,
|
||||
long oldValue, long addend, boolean isGpDisp) {
|
||||
this.relocType = relocType;
|
||||
this.elfSymbol = elfSymbol;
|
||||
this.relocAddr = relocAddr;
|
||||
this.oldValue = oldValue;
|
||||
this.addend = addend;
|
||||
this.oldValueL = oldValue;
|
||||
this.addendL = addend;
|
||||
this.isGpDisp = isGpDisp;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user