diff --git a/Ghidra/Processors/RISCV/data/languages/riscv32-fp.cspec b/Ghidra/Processors/RISCV/data/languages/riscv32-fp.cspec
index d2dc46591a..fcab73299f 100644
--- a/Ghidra/Processors/RISCV/data/languages/riscv32-fp.cspec
+++ b/Ghidra/Processors/RISCV/data/languages/riscv32-fp.cspec
@@ -17,7 +17,7 @@
-
+
@@ -30,103 +30,178 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Ghidra/Processors/RISCV/data/languages/riscv32.cspec b/Ghidra/Processors/RISCV/data/languages/riscv32.cspec
index 4a08e655d9..7686bf9b9a 100644
--- a/Ghidra/Processors/RISCV/data/languages/riscv32.cspec
+++ b/Ghidra/Processors/RISCV/data/languages/riscv32.cspec
@@ -15,7 +15,7 @@
-
+
@@ -28,43 +28,64 @@
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
+
+
+
+
@@ -83,6 +104,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Processors/RISCV/data/languages/riscv64-fp.cspec b/Ghidra/Processors/RISCV/data/languages/riscv64-fp.cspec
index 329cb033b5..c01a51e02f 100644
--- a/Ghidra/Processors/RISCV/data/languages/riscv64-fp.cspec
+++ b/Ghidra/Processors/RISCV/data/languages/riscv64-fp.cspec
@@ -30,103 +30,178 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Processors/RISCV/data/languages/riscv64.cspec b/Ghidra/Processors/RISCV/data/languages/riscv64.cspec
index 1fe4fe3f9b..ec263444bb 100644
--- a/Ghidra/Processors/RISCV/data/languages/riscv64.cspec
+++ b/Ghidra/Processors/RISCV/data/languages/riscv64.cspec
@@ -28,35 +28,52 @@
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -65,6 +82,10 @@
+
+
+
+
@@ -83,6 +104,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationHandler.java b/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationHandler.java
index a48257d9db..b836357859 100644
--- a/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationHandler.java
+++ b/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_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.
@@ -154,7 +154,7 @@ public class RISCV_ElfRelocationHandler
long base = elfRelocationContext.getImageBaseWordAdjustmentOffset();
int symbolIndex = relocation.getSymbolIndex();
-
+
long value64 = 0;
int value32 = 0;
short value16 = 0;
@@ -162,7 +162,7 @@ public class RISCV_ElfRelocationHandler
int target = 0;
int byteLength = 4; // most relocations affect 4-bytes (change if different)
-
+
// Handle relative relocations that do not require symbolAddr or symbolValue
switch (type) {
@@ -178,7 +178,7 @@ public class RISCV_ElfRelocationHandler
byteLength = 8;
}
return new RelocationResult(Status.APPLIED, byteLength);
-
+
case R_RISCV_PCREL_LO12_S:
// PC-relative reference %pcrel_lo(symbol) (S-Type)
// S-type immediates split the 12 bit value into separate 7 bit and 5 bit fields.
@@ -194,7 +194,7 @@ public class RISCV_ElfRelocationHandler
(memory.getInt(relocationAddress) & 0x1fff07f);
memory.setInt(relocationAddress, value32);
return new RelocationResult(Status.APPLIED, byteLength);
-
+
case R_RISCV_PCREL_LO12_I:
// PC-relative reference %pcrel_lo(symbol) (I-Type), relative to the cited pc_rel_hi20
target = getSymbolValueIndirect(elfRelocationContext, sym,
@@ -208,21 +208,21 @@ public class RISCV_ElfRelocationHandler
((target & 0x00000fff) << 20) | (memory.getInt(relocationAddress) & 0xfffff);
memory.setInt(relocationAddress, value32);
return new RelocationResult(Status.APPLIED, byteLength);
-
+
case R_RISCV_COPY:
// Runtime relocation must be in executable. not allowed in shared library
markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex,
sym.getSize(), elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
-
+
default:
break;
}
-
+
// Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below
if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) {
return RelocationResult.FAILURE;
- }
+ }
switch (type) {
case R_RISCV_32:
@@ -322,21 +322,21 @@ public class RISCV_ElfRelocationHandler
case R_RISCV_HI20:
// Absolute address %hi(symbol) (U-Type)
- value32 = (int) ((symbolValue + 0x800) & 0xfffff000) |
+ value32 = (int) ((addend + symbolValue + 0x800) & 0xfffff000) |
(memory.getInt(relocationAddress) & 0xfff);
memory.setInt(relocationAddress, value32);
break;
case R_RISCV_LO12_I:
// Absolute address %lo(symbol) (I-Type)
- value32 = ((int) (symbolValue & 0x00000fff) << 20) |
+ value32 = ((int) ((addend + symbolValue) & 0x00000fff) << 20) |
(memory.getInt(relocationAddress) & 0xfffff);
memory.setInt(relocationAddress, value32);
break;
case R_RISCV_LO12_S:
// Absolute address %lo(symbol) (S-Type)
- value32 = (int) (symbolValue & 0x00000fff);
+ value32 = (int) ((addend + symbolValue) & 0x00000fff);
value32 = ((value32 & 0x1f) << 7) | ((value32 & 0xfe0) << 20) |
(memory.getInt(relocationAddress) & 0x1fff07f);
memory.setInt(relocationAddress, value32);