Merge remote-tracking branch 'origin/patch'

This commit is contained in:
Ryan Kurtz
2025-08-27 04:56:05 -04:00
13 changed files with 210 additions and 401 deletions
@@ -1,3 +1,21 @@
# Ghidra 11.4.2 Change History (August 2025)
### Improvements
* _Build_. Ghidra now supports Gradle 9. (GP-5901)
* _Decompiler_. Improved Decompiler's analysis of switches where the guard condition has been duplicated across multiple basic blocks that all feed into the same switch calculation. (GP-5889)
* _Processors_. Added the SuperH GBR register to the unaffected list in the `.cspec` so that the Decompiler sees the value as preserved across subroutine calls. (GP-5912, Issue #4387)
### Bugs
* _Analysis_. Fixed switch recovery analysis speed degredation on functions with multiple potential switches. (GP-5917)
* _Decompiler_. Fixed a bug in the Decompiler's analysis of duplicated boolean expressions that could reverse the meaning of an expression. (GP-5915, Issue #8310)
* _Decompiler_. Fixed an uncaught exception in the Decompiler that resulted when `highSymbol` was null. (GP-5919, Issue #8413)
* _Exporter_. The `IntelHexExpoter` no longer fails due to falsely identifying a 32-bit program as 64-bit. Additionally, the address space option is no longer hidden. (GP-5910, Issue #8409)
* _Importer:ELF_. Corrected ELF MIPS-64 packed REL relocation processing issue seen when the relocation type R_MIPS_REL32 is included (e.g., packed type 0x1203). When 64-bit pointers are used, this relocation must read 8 bytes from memory instead of 4 bytes to produce the correct addend value. (GP-5918)
* _Importer:PE_. Fixed a regression that caused bad functions to be created in the middle of good functions in PE files with chained `IMAGE_FUNCTION_RUNTIME_ENTRY`s, and prevented some PE binaries from importing. (GP-5916, Issue #8414)
* _Importer:PE_. The `IMAGE_RESOURCE_DIRECTORY_ENTRY` data type is now correctly defined as a structure instead of a union. (GP-5935, Issue #8446)
* _PDB_. Fixed structure member issue, broken with 11.4 release, that could cause improper structure layout and Decompiler low-level errors. (GP-5928)
* _Processors_. Added additional SPE and APU instructions to e500 PowerPC variant. (GP-5945)
# Ghidra 11.4.1 Change History (July 2025)
### Improvements
File diff suppressed because it is too large Load Diff
@@ -1137,9 +1137,9 @@
# evlwhe RT,D(RA)
# evlwhe rT,rA,UI
:evlwhe D,EVUIMM_4_RAt is OP=4 & D & EVUIMM_4_RAt & RA_OR_ZERO & UI & XOP_0_10=785
:evlwhe D,EVUIMM_4_RAt is OP=4 & D & EVUIMM_4_RAt & XOP_0_10=785
{
ea:$(REGISTER_SIZE) = RA_OR_ZERO + (UI * 4);
ea:$(REGISTER_SIZE) = EVUIMM_4_RAt;
# move results into upper and lower words
tmpZ:8 = zext( *:2(ea + 2) );
@@ -1179,9 +1179,9 @@
# ISA-info: evlwwsplat - Form "EVX" Page 521 Category "SP"
# binutils: NO-EXAMPLE - evlwwsplat
# collides with maclhwu
:evlwwsplat D,EVUIMM_4_RAt is OP=4 & D & RA_OR_ZERO & EVUIMM_4_RAt & UI & XOP_0_10=793
:evlwwsplat D,EVUIMM_4_RAt is OP=4 & D & EVUIMM_4_RAt & XOP_0_10=793
{
ea:$(REGISTER_SIZE) = RA_OR_ZERO + (UI * 4);
ea:$(REGISTER_SIZE) = EVUIMM_4_RAt;
# move results into upper and lower words
tmpZ:8 = zext( *:4(ea) );
@@ -1413,10 +1413,34 @@
tmpAL:8 = zext( A:4 );
tmpBL:8 = zext( B:4 );
D = tmpAL * tmpBL;
temp:8 = tmpAL * tmpBL;
D = temp;
}
# evmwumia RT,RA,RB
# ISA-cmt: Vector Multiply Word Unsigned, Modulo, Integer to Accumulator
# evmwumia rD,rA,rB 100 01A1 1000 A=1
:evmwumia D,A,B is OP=4 & A & B & D & XOP_0_10=0x478 {
tmpAL:8 = zext( A:4 );
tmpBL:8 = zext( B:4 );
temp:8 = tmpAL * tmpBL;
D = temp;
ACC = D;
}
# evmwumiaa RT,RA,RB
# ISA-cmt: Vector Multiply Word Unsigned, Modulo, Integer and Accumulate
# evmwumiaa rD,rA,rB 101 0101 1000
# evmwumiaa confict with macchwo
:evmwumiaa D,A,B is OP=4 & A & B & D & XOP_0_10=0x558 {
tmpAL:8 = zext( A:4 );
tmpBL:8 = zext( B:4 );
temp:8 = tmpAL * tmpBL;
D = ACC + temp;
ACC = D;
}
# =================================================================
# Page 547
@@ -4,120 +4,6 @@
@include "SPE_APU.sinc"
@endif
define pcodeop vectorExclusiveOr;
define pcodeop vectorMergeHigh;
define pcodeop vectorMergeLow;
define pcodeop vectorLoadDoubleWordIntoDoubleWordIndexed;
define pcodeop vectorStoreDoubleOfDoubleIndexed;
define pcodeop initializeAccumulator;
define pcodeop vectorShiftRightWordSigned;
define pcodeop vectorShiftRightWordUnsigned;
:evxor vrD_64_0,vrA_64_0,vrB_64_0 is OP=4 & vrD_64_0 & vrA_64_0 & vrB_64_0 & XOP_0_10=534
{
vrD_64_0 = vrA_64_0 ^ vrB_64_0;
}
@if REGISTER_SIZE=="8"
:evmergehi S,A,B is OP=4 & S & A & B & XOP_0_10=556
{
S[32,32] = A[32,32];
S[ 0,32] = B[ 0,32];
}
:evmergelo S,A,B is OP=4 & S & A & B & XOP_0_10=557
{
S[32,32] = A[0,32];
S[ 0,32] = B[0,32];
}
@endif
:evldd RT,dUI16PlusRAOrZeroAddress is OP=4 & RT & dUI16PlusRAOrZeroAddress & XOP_0_10=769
{
ea:$(REGISTER_SIZE) = dUI16PlusRAOrZeroAddress;
RT = *:8 ($(EATRUNC));
}
:evlddx RT,RA_OR_ZERO,RB is OP=4 & RT & RA_OR_ZERO & RB & XOP_0_10=768
{
ea:$(REGISTER_SIZE) = RA_OR_ZERO + RB;
RT = *:8 ($(EATRUNC));
}
@if REGISTER_SIZE=="8"
@ifndef IS_ISA
:evsrws S,A,B is OP=4 & S & A & B & XOP_0_10=545
{
local low:4 = A[0,32];
local high:4 = A[32,32];
local low_shift:1 = B[0,5];
local high_shift:1 = B[32,5];
S[0,32] = low s>> zext(low_shift);
S[32,32] = high s>> zext(high_shift);
}
@endif
@ifndef IS_ISA
:evsrwu S,A,B is OP=4 & S & A & B & XOP_0_10=544
{
local low:4 = A[0,32];
local high:4 = A[32,32];
local low_shift:1 = B[0,5];
local high_shift:1 = B[32,5];
S[0,32] = low >> zext(low_shift);
S[32,32] = high >> zext(high_shift);
}
@endif
@endif
:evstdd RS,dUI16PlusRAOrZeroAddress is OP=4 & RS & dUI16PlusRAOrZeroAddress & XOP_0_10=801
{
ea:$(REGISTER_SIZE) = dUI16PlusRAOrZeroAddress;
*:8 ($(EATRUNC)) = RS;
}
:evstddx RS,RA_OR_ZERO,RB is OP=4 & RS & RA_OR_ZERO & RB & XOP_0_10=800
{
ea:$(REGISTER_SIZE) = RA_OR_ZERO + RB;
*:8 ($(EATRUNC)) = RS;
}
:evmra RT,RA is OP=4 & RT & RA & BITS_11_15=0 & XOP_0_10=1220
{
ACC = zext(RA);
RT = RA;
}
@if REGISTER_SIZE=="8"
# evmergehilo rD,rA,rB 010 0010 1110
:evmergehilo S,A,B is OP=4 & S & A & B & XOP_0_10=558 {
S[32,32] = A[32,32];
S[ 0,32] = B[ 0,32];
}
# evmergelohi rD,rA,rB 010 0010 1111
:evmergelohi S,A,B is OP=4 & S & A & B & XOP_0_10=559 {
S[32,32] = A[ 0,32];
S[ 0,32] = B[32,32];
}
@endif
# evstwwe rS,rA,UIMM 011 0011 1001
:evstwwe RS,dUI16PlusRAOrZeroAddress is OP=4 & RS & dUI16PlusRAOrZeroAddress & XOP_0_10=0x339
{
ea:$(REGISTER_SIZE) = dUI16PlusRAOrZeroAddress;
*:4 ($(EATRUNC)) = RS:4;
}
# evstwwex rS,rA,rB 011 0011 1000
:evstwwex RS,RA_OR_ZERO,RB is OP=4 & RS & RA_OR_ZERO & RB & XOP_0_10=0x338
{
ea:$(REGISTER_SIZE) = RA_OR_ZERO + RB;
*:4 ($(EATRUNC)) = RS:4;
}
:lvx vrD, RA_OR_ZERO, RB is OP=31 & vrD & RA_OR_ZERO & RB & XOP_1_10=103 & BIT_0=0
{
ea:$(REGISTER_SIZE) = RA_OR_ZERO + RB;
@@ -4,7 +4,7 @@
# by the actual processor (e.g., floating pointer registers and associated instructions).
# The actual processor only supports a subset of the registers and instructions implemented.
@define E500
@define E500 "1"
@define ENDIAN "big"
@@ -19,10 +19,11 @@
@define CTR_OFFSET "32"
@define NoLegacyIntegerMultiplyAccumulate
@define NoLegacyIntegerMultiplyAccumulate "1"
@include "ppc_common.sinc"
@include "quicciii.sinc"
@include "SPE_APU.sinc"
@include "evx.sinc"
@include "SPEF_SCR.sinc"
@include "SPE_EFSD.sinc"
@@ -4,7 +4,7 @@
# by the actual processor (e.g., floating pointer registers and associated instructions).
# The actual processor only supports a subset of the registers and instructions implemented.
@define E500
@define E500 "1"
@define ENDIAN "little"
@@ -19,10 +19,11 @@
@define CTR_OFFSET "32"
@define NoLegacyIntegerMultiplyAccumulate
@define NoLegacyIntegerMultiplyAccumulate "1"
@include "ppc_common.sinc"
@include "quicciii.sinc"
@include "SPE_APU.sinc"
@include "evx.sinc"
@include "SPEF_SCR.sinc"
@include "SPE_EFSD.sinc"
@@ -14,7 +14,7 @@
#
@define CTR_OFFSET "32"
@define NoLegacyIntegerMultiplyAccumulate
@define NoLegacyIntegerMultiplyAccumulate "1"
@include "ppc_common.sinc"
@include "quicciii.sinc"
@@ -12,7 +12,7 @@
#
@define CTR_OFFSET "32"
@define NoLegacyIntegerMultiplyAccumulate
@define NoLegacyIntegerMultiplyAccumulate "1"
@include "ppc_common.sinc"
@include "quicciii.sinc"
@@ -1064,9 +1064,14 @@ define token instrvle(16)
LK0_VLE=(0,0)
;
EVUIMM_2_RAt: val^"("^A^")" is A & EVUIMM_2 [ val = EVUIMM_2*2; ] { tmp:4 = A+(EVUIMM_2*2); export tmp; }
EVUIMM_4_RAt: val^"("^A^")" is A & EVUIMM_4 [ val = EVUIMM_4*4; ] { tmp:4 = A+(EVUIMM_4*4); export tmp; }
EVUIMM_8_RAt: val^"("^A^")" is A & EVUIMM_8 [ val = EVUIMM_8*8; ] { tmp:4 = A+(EVUIMM_8*8); export tmp; }
EVUIMM_2_RAt: val^"("^RA^")" is RA & A & EVUIMM_2 [ val = EVUIMM_2*2; ] { tmp:$(REGISTER_SIZE) = RA+zext(val:4); export tmp; }
EVUIMM_2_RAt: val^"("^RA^")" is RA & A=0 & EVUIMM_2 [ val = EVUIMM_2*2; ] { tmp:$(REGISTER_SIZE) = zext(val:4); export tmp; }
EVUIMM_4_RAt: val^"("^RA^")" is RA & A & EVUIMM_4 [ val = EVUIMM_4*4; ] { tmp:$(REGISTER_SIZE) = RA+zext(val:4); export tmp; }
EVUIMM_4_RAt: val^"("^RA^")" is RA & A=0 & EVUIMM_4 [ val = EVUIMM_4*4; ] { tmp:$(REGISTER_SIZE) = zext(val:4); export tmp; }
EVUIMM_8_RAt: val^"("^RA^")" is RA & A & EVUIMM_8 [ val = EVUIMM_8*8; ] { tmp:$(REGISTER_SIZE) = RA+zext(val:4); export tmp; }
EVUIMM_8_RAt: val^"("^RA^")" is RA & A=0 & EVUIMM_8 [ val = EVUIMM_8*8; ] { tmp:$(REGISTER_SIZE) = zext(val:4); export tmp; }
attach variables [ T ]
[ vs0 vs1 vs2 vs3 vs4 vs5 vs6 vs7 vs8 vs9 vs10 vs11 vs12 vs13 vs14 vs15
@@ -49,6 +49,13 @@
dataCacheBlockClearToZero(ea);
}
#dcbzl 0,r0 0x7c 20 07 ec
:dcbzl RA_OR_ZERO,B is OP=31 & BITS_21_25=1 & B & XOP_1_10=1014 & BIT_0=0 & RA_OR_ZERO
{
ea:$(REGISTER_SIZE) = RA_OR_ZERO + B;
dataCacheBlockClearToZero(ea);
}
define pcodeop memoryBarrier;
#mbar 0 7c 00 06 ac
:mbar MO is OP=31 & MO & XOP_1_10=854
@@ -829,17 +829,17 @@ IMM16B: val is IMM_0_10_VLE & IMM_16_20_VLE [ val = (IMM_16_20_VLE << 11) |
tmpS:4 = S:4;
tmpA:4 = (tmpS << SHL) | (tmpS >> (32 - SHL));
tmpM1 = (~0:4) << MBL;
tmpM1 = tmpM1 >> ((31-ME) + MBL);
tmpM1 = tmpM1 << (31-ME);
tmpM1:4 = (~0:4) << MBL;
tmpM1 = tmpM1 >> ((31-ME) + MBL);
tmpM1 = tmpM1 << (31-ME);
tmpM2 = (~0:4) << ME;
tmpM2 = tmpM2 >> ((31-MBL) + ME);
tmpM2 = tmpM2 << (31-MBL);
tmpM2 = ~tmpM2;
tmpM2:4 = (~0:4) << ME;
tmpM2 = tmpM2 >> ((31-MBL) + ME);
tmpM2 = tmpM2 << (31-MBL);
tmpM2 = ~tmpM2;
local invert = (ME:1 < MBL:1);
tmpM = (zext(invert == 0)*tmpM1) + (zext(invert == 1)*tmpM2);
tmpM:4 = (zext(invert == 0)*tmpM1) + (zext(invert == 1)*tmpM2);
A = zext(tmpA & tmpM) | (A & zext(~tmpM));
}
@@ -847,17 +847,17 @@ IMM16B: val is IMM_0_10_VLE & IMM_16_20_VLE [ val = (IMM_16_20_VLE << 11) |
tmpS:4 = S:4;
tmpA:4 = (tmpS << SHL) | (tmpS >> (32 - SHL));
tmpM1 = (~0:4) << MBL;
tmpM1 = tmpM1 >> ((31-ME) + MBL);
tmpM1 = tmpM1 << (31-ME);
tmpM1:4 = (~0:4) << MBL;
tmpM1 = tmpM1 >> ((31-ME) + MBL);
tmpM1 = tmpM1 << (31-ME);
tmpM2 = (~0:4) << ME;
tmpM2:4 = (~0:4) << ME;
tmpM2 = tmpM2 >> ((31-MBL) + ME);
tmpM2 = tmpM2 << (31-MBL);
tmpM2 = ~tmpM2;
local invert = (ME:1 < MBL:1);
tmpM = (zext(invert == 0)*tmpM1) + (zext(invert == 1)*tmpM2);
tmpM:4 = (zext(invert == 0)*tmpM1) + (zext(invert == 1)*tmpM2);
A = zext(tmpA & tmpM);
}
@@ -6,6 +6,7 @@
</prepatterns>
<postpatterns>
<data>10010100 00100001 11...... .....000 </data> <!-- STWU r1,xx(r1) -->
<data>011111.. ...01000 00000010 10100110 </data> <!-- MFSPR rx,lr -->
<data>0x7c2c0b78 0x38 0x21 ........ ........ 0x91810000 </data> <!-- or r12,r1,r1; stw r12,0x0(r1) -->
<codeboundary /> <!-- it is at least code -->
<possiblefuncstart/>
@@ -17,8 +18,11 @@
</prepatterns>
<postpatterns>
<data>10010100 00100001 11...... .....000 011111.. ...01000 00000010 10100110 </data> <!-- STWU r1,xx(r1); MFSPR rx,lr -->
<data>011111.. ...01000 00000010 10100110 10010100 00100001 11...... .....000 </data> <!-- MFSPR rx,lr; STWU r1,xx(r1); -->
<data>10010100 00100001 11...... .....000 0x........ 011111.. ...01000 00000010 10100110 </data> <!-- STWU r1,xx(r1); xxx_instr; MFSPR rx,lr -->
<data>011111.. ...01000 00000010 10100110 0x........ 10010100 00100001 11...... .....000 </data> <!-- MFSPR rx,lr; xxx_instr; STWU r1,xx(r1) -->
<data>10010100 00100001 11...... .....000 0x........ 0x........ 011111.. ...01000 00000010 10100110 </data> <!-- STWU r1,xx(r1); xxx_instr; xxx_instr; MFSPR rx,lr -->
<data>011111.. ...01000 00000010 10100110 0x........ 0x........ 10010100 00100001 11...... .....000 </data> <!-- MFSPR rx,lr; xxx_instr; xxx_instr; STWU r1,xx(r1) -->
<data>0x7c2c0b78 0x38 0x21 ........ ........ 0x91810000 </data> <!-- or r12,r1,r1; stw r12,0x0(r1) -->
<codeboundary /> <!-- it is at least code -->
<possiblefuncstart/>
@@ -31,6 +35,12 @@
<possiblefuncstart after="defined" /> <!-- must be something defined right before this -->
</pattern>
<pattern>
<data>011111.. ...01000 00000010 10100110 10010100 00100001 11...... .....000 </data> <!-- MFSPR rx,lr; STWU r1,xx(r1) -->
<codeboundary />
<possiblefuncstart after="defined" /> <!-- must be something defined right before this -->
</pattern>
<pattern>
<data> 0x4e 0x80 0x00 0x21</data> <!-- blrl -->
<possiblefuncstart validcode="function" label="__get_pc_thunk_lr" /> <!-- must be a function here -->
@@ -6,6 +6,7 @@
</prepatterns>
<postpatterns>
<data>.....000 11...... 00100001 10010100 </data> <!-- STWU r1,xx(r1) -->
<data>10100110 00000010 ...01000 011111.. </data> <!-- MFSPR rx,lr -->
<data>0x780b2c7c ........ ........ 0x21 0x38 0x00008191 </data> <!-- or r12,r1,r1; stw r12,0x0(r1) -->
<codeboundary /> <!-- it is at least code -->
<possiblefuncstart/>
@@ -17,8 +18,11 @@
</prepatterns>
<postpatterns>
<data>.....000 11...... 00100001 10010100 10100110 00000010 ...01000 011111.. </data> <!-- STWU r1,xx(r1); MFSPR rx,lr -->
<data>10100110 00000010 ...01000 011111.. .....000 11...... 00100001 10010100 </data> <!-- MFSPR rx,lr; STWU r1,xx(r1); -->
<data>.....000 11...... 00100001 10010100 0x........ 10100110 00000010 ...01000 011111.. </data> <!-- STWU r1,xx(r1); xxx_instr; MFSPR rx,lr -->
<data>10100110 00000010 ...01000 011111.. 0x........ .....000 11...... 00100001 10010100 </data> <!-- MFSPR rx,lr; xxx_instr; STWU r1,xx(r1) -->
<data>.....000 11...... 00100001 10010100 0x........ 0x........ 10100110 00000010 ...01000 011111.. </data> <!-- STWU r1,xx(r1); xxx_instr; xxx_instr; MFSPR rx,lr -->
<data>10100110 00000010 ...01000 011111.. 0x........ 0x........ .....000 11...... 00100001 10010100 </data> <!-- MFSPR rx,lr; xxx_instr; xxx_instr; STWU r1,xx(r1) -->
<data>0x780b2c7c ........ ........ 0x21 0x38 0x00008191 </data> <!-- or r12,r1,r1; stw r12,0x0(r1) -->
<codeboundary /> <!-- it is at least code -->
<possiblefuncstart/>
@@ -31,6 +35,12 @@
<possiblefuncstart after="defined" /> <!-- must be something defined right before this -->
</pattern>
<pattern>
<data>10100110 00000010 ...01000 011111.. .....000 11...... 00100001 10010100 </data> <!-- MFSPR rx,lr; STWU r1,xx(r1) -->
<codeboundary />
<possiblefuncstart after="defined" /> <!-- must be something defined right before this -->
</pattern>
<pattern>
<data>0x21 0x00 0x80 0x4e</data> <!-- blrl -->
<possiblefuncstart validcode="function" label="__get_pc_thunk_lr" /> <!-- must be a function here -->