From 836604e09d84012d83432c60504cf0fdd65e832b Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Mon, 27 Mar 2023 19:10:19 -0400 Subject: [PATCH] GP-3260 Corrected MIPS relocation issues and a few related issues affecting listing markup --- .../app/util/opinion/ElfProgramBuilder.java | 95 +++--- .../program/model/listing/CodeUnitFormat.java | 5 +- .../program/util/SymbolicPropogator.java | 3 +- .../datatype/finder/DecompilerReference.java | 4 +- .../references/OffsetReferenceDB.java | 4 +- .../ComponentOffsetSettingsDefinition.java | 7 +- .../program/model/reloc/Relocation.java | 10 + .../format/elf/extend/MIPS_ElfExtension.java | 38 ++- .../elf/relocation/MIPS_Elf64Relocation.java | 3 +- .../MIPS_ElfRelocationConstants.java | 9 + .../relocation/MIPS_ElfRelocationContext.java | 2 + .../relocation/MIPS_ElfRelocationHandler.java | 321 +++++++++--------- 12 files changed, 266 insertions(+), 235 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java index c3b3ab65de..bc475af2cf 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java @@ -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 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 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 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 { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/model/listing/CodeUnitFormat.java b/Ghidra/Features/Base/src/main/java/ghidra/program/model/listing/CodeUnitFormat.java index a99e432b3a..b0e9ec71bb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/model/listing/CodeUnitFormat.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/model/listing/CodeUnitFormat.java @@ -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); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java index 38e4f1f8ea..78071a27d2 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java @@ -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; } diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerReference.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerReference.java index eb30d9d0d2..5dcda5e5b0 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerReference.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerReference.java @@ -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; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/OffsetReferenceDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/OffsetReferenceDB.java index 5dfad00b32..ba39b7faa2 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/OffsetReferenceDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/OffsetReferenceDB.java @@ -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; } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/ComponentOffsetSettingsDefinition.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/ComponentOffsetSettingsDefinition.java index 563fbf5b56..c9918b47aa 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/ComponentOffsetSettingsDefinition.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/ComponentOffsetSettingsDefinition.java @@ -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; } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/reloc/Relocation.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/reloc/Relocation.java index 76099b9475..37955104e7 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/reloc/Relocation.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/reloc/Relocation.java @@ -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 null if there is no symbol name. * diff --git a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/extend/MIPS_ElfExtension.java b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/extend/MIPS_ElfExtension.java index 57e5b64603..9e961c4b60 100644 --- a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/extend/MIPS_ElfExtension.java +++ b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/extend/MIPS_ElfExtension.java @@ -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); } diff --git a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_Elf64Relocation.java b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_Elf64Relocation.java index c1f3387ec4..ea2864d2dc 100644 --- a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_Elf64Relocation.java +++ b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_Elf64Relocation.java @@ -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() { diff --git a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationConstants.java b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationConstants.java index c4faad26b6..8187e885cb 100644 --- a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationConstants.java +++ b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationConstants.java @@ -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 diff --git a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationContext.java b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationContext.java index d59589e956..c71d3a3eac 100644 --- a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationContext.java +++ b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationContext.java @@ -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(); } diff --git a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java index 6543e6e528..78ebab1e04 100644 --- a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java +++ b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java @@ -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; }