From 2dd02db1c365b36c56441dec15734271e72b227e Mon Sep 17 00:00:00 2001 From: emteere <47253321+emteere@users.noreply.github.com> Date: Mon, 9 Sep 2024 09:57:48 -0400 Subject: [PATCH] GP-3808a Minor fixes for sparc relocations after merge --- .../SPARC64_ElfRelocationHandler.java | 88 +++++++++++-------- .../SPARC_ElfRelocationHandler.java | 15 +--- 2 files changed, 54 insertions(+), 49 deletions(-) diff --git a/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC64_ElfRelocationHandler.java b/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC64_ElfRelocationHandler.java index e8bd240b2d..78c7424517 100644 --- a/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC64_ElfRelocationHandler.java +++ b/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC64_ElfRelocationHandler.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -44,69 +44,85 @@ public class SPARC64_ElfRelocationHandler extends SPARC_ElfRelocationHandler { long pc = relocationAddress.getOffset(); int oldIntValue = memory.getInt(relocationAddress); - int newIntValue = 0; - long newLongValue = 0; + long newValue = 0; int mask = 0; int byteLength = 8; // most relocations affect 8-bytes (change if different) + // Handle relative relocations that do not require symbolAddr or symbolValue + switch (type) { + case R_SPARC_RELATIVE: + newValue = elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend; + memory.setLong(relocationAddress, newValue); + return new RelocationResult(Status.APPLIED, byteLength); + + case R_SPARC_COPY: + int symbolIndex = relocation.getSymbolIndex(); + markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, + sym.getSize(), elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + + case R_SPARC_SIZE64: + newValue = sym.getSize() + addend; + memory.setLong(relocationAddress, newValue); + break; + + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } + // Relocation docs: https://docs.oracle.com/cd/E19120-01/open.solaris/819-0690/chapter6-24-1/index.html // switch (type) { case R_SPARC_HI22: - newIntValue = (int) ((symbolValue + addend) >>> 10); + newValue = (int) ((symbolValue + addend) >>> 10); mask = 0x003fffff; oldIntValue &= ~(mask); - newIntValue &= mask; - memory.setInt(relocationAddress, oldIntValue | newIntValue); + newValue &= mask; + memory.setInt(relocationAddress, oldIntValue | (int) newValue); byteLength = 4; break; case R_SPARC_OLO10: - newIntValue = (int) ((symbolValue + addend) & 0x3FF) + (int)((relocation.getRelocationInfo()<<32)>>40); + newValue = (int) ((symbolValue + addend) & 0x3FF) + (int)((relocation.getRelocationInfo()<<32)>>40); mask = 0x00001fff; oldIntValue &= ~(mask); - newIntValue &= mask; - memory.setInt(relocationAddress, oldIntValue | newIntValue); + newValue &= mask; + memory.setInt(relocationAddress, oldIntValue | (int) newValue); byteLength = 4; break; case R_SPARC_GLOB_DAT: - newLongValue = symbolValue + addend; - memory.setLong(relocationAddress, newLongValue); - break; - - case R_SPARC_RELATIVE: - newLongValue = elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend; - memory.setLong(relocationAddress, newLongValue); + newValue = symbolValue + addend; + memory.setLong(relocationAddress, newValue); break; case R_SPARC_64: - newLongValue = symbolValue + addend; - memory.setLong(relocationAddress, newLongValue); + newValue = symbolValue + addend; + memory.setLong(relocationAddress, newValue); break; case R_SPARC_DISP64: - newLongValue = symbolValue + addend - pc; - memory.setLong(relocationAddress, newLongValue); + newValue = symbolValue + addend - pc; + memory.setLong(relocationAddress, newValue); break; case R_SPARC_UA64: case R_SPARC_REGISTER: - newLongValue = symbolValue + addend; - memory.setLong(relocationAddress, newLongValue); - break; - - case R_SPARC_SIZE64: - newLongValue = sym.getSize() + addend; - memory.setLong(relocationAddress, newLongValue); + newValue = symbolValue + addend; + memory.setLong(relocationAddress, newValue); break; case R_SPARC_H34: - newIntValue = (int) ((symbolValue + addend) >>> 12); + newValue = (int) ((symbolValue + addend) >>> 12); mask = 0x003fffff; oldIntValue &= ~(mask); - newIntValue &= mask; - memory.setInt(relocationAddress, oldIntValue | newIntValue); + newValue &= mask; + memory.setInt(relocationAddress, oldIntValue | (int) newValue); byteLength = 4; break; @@ -122,12 +138,12 @@ public class SPARC64_ElfRelocationHandler extends SPARC_ElfRelocationHandler { // this is not the way JMP_SLOT is always done, but it should work in all cases of a large 64-bit address // other variants are optimized to handle smaller address values - newLongValue = (symbolValue + addend); + newValue = (symbolValue + addend); - long hh = newLongValue >> 42; - long hl = (newLongValue >> 32) & 0x3ff; - long lh = (newLongValue & 0xffffffff) >> 10; - long ll = newLongValue & 0x3ff; + long hh = newValue >> 42; + long hl = (newValue >> 32) & 0x3ff; + long lh = (newValue & 0xffffffff) >> 10; + long ll = newValue & 0x3ff; memory.setInt(relocationAddress, (int) (sparc_sethi_g1 | hh)); memory.setInt(relocationAddress.add(4), (int) (sparc_sethi_g5 | lh)); diff --git a/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationHandler.java b/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationHandler.java index 8d2b5fb80b..eabf575eeb 100644 --- a/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationHandler.java +++ b/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationHandler.java @@ -62,9 +62,8 @@ public class SPARC_ElfRelocationHandler // Handle relative relocations that do not require symbolAddr or symbolValue switch (type) { - case R_SPARC_RELATIVE: - newValue = (int) elfRelocationContext.getElfHeader().getImageBase() + (int) addend; + newValue = elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend; memory.setInt(relocationAddress, (int) newValue); return new RelocationResult(Status.APPLIED, byteLength); @@ -72,7 +71,7 @@ public class SPARC_ElfRelocationHandler markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, sym.getSize(), elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; - + default: break; } @@ -209,11 +208,6 @@ public class SPARC_ElfRelocationHandler memory.setInt(relocationAddress, (int) newValue); break; - case R_SPARC_RELATIVE: - newValue = elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend; - memory.setInt(relocationAddress, (int) newValue); - break; - case R_SPARC_UA32: newValue = symbolValue + addend; memory.setInt(relocationAddress, (int) newValue); @@ -369,11 +363,6 @@ public class SPARC_ElfRelocationHandler newValue &= mask; memory.setInt(relocationAddress, oldValue | (int) newValue); break; - - case R_SPARC_COPY: - markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, - sym.getSize(), elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; default: markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName,