Merge remote-tracking branch 'origin/GP-4474_emteere_PPC_blrl_PIC'

This commit is contained in:
Ryan Kurtz
2024-04-16 12:14:53 -04:00
12 changed files with 108 additions and 1 deletions

View File

@@ -63,5 +63,6 @@ data/languages/vsx.sinc||GHIDRA||||END|
data/manuals/PowerISA.idx||GHIDRA||||END|
data/manuals/PowerPC.idx||GHIDRA||||END|
data/patterns/PPC_BE_patterns.xml||GHIDRA||||END|
data/patterns/PPC_LE_patterns.xml||GHIDRA||||END|
data/patterns/patternconstraints.xml||GHIDRA||||END|
data/ppc64-r2CallStubs.xml||GHIDRA||||END|

View File

@@ -116,6 +116,7 @@
</default_proto>
<callfixup name="get_pc_thunk_lr">
<target name="__get_pc_thunk_lr"/>
<pcode>
<body><![CDATA[
LR = inst_dest + 4;

View File

@@ -72,6 +72,7 @@
</default_proto>
<callfixup name="get_pc_thunk_lr">
<target name="__get_pc_thunk_lr"/>
<pcode>
<body><![CDATA[
LR = inst_dest + 4;

View File

@@ -71,6 +71,7 @@
</default_proto>
<callfixup name="get_pc_thunk_lr">
<target name="__get_pc_thunk_lr"/>
<pcode>
<body><![CDATA[
LR = inst_dest + 4;

View File

@@ -70,6 +70,7 @@
</default_proto>
<callfixup name="get_pc_thunk_lr">
<target name="__get_pc_thunk_lr"/>
<pcode>
<body><![CDATA[
LR = inst_dest + 4;

View File

@@ -70,6 +70,7 @@
</default_proto>
<callfixup name="get_pc_thunk_lr">
<target name="__get_pc_thunk_lr"/>
<pcode>
<body><![CDATA[
LR = inst_dest + 4;

View File

@@ -116,6 +116,7 @@
</default_proto>
<callfixup name="get_pc_thunk_lr">
<target name="__get_pc_thunk_lr"/>
<pcode>
<body><![CDATA[
LR = inst_dest + 4;

View File

@@ -119,6 +119,7 @@
</default_proto>
<callfixup name="get_pc_thunk_lr">
<target name="__get_pc_thunk_lr"/>
<pcode>
<body><![CDATA[
LR = inst_dest + 4;

View File

@@ -31,4 +31,9 @@
<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 -->
</pattern>
</patternlist>

View File

@@ -0,0 +1,39 @@
<patternlist>
<patternpairs totalbits="32" postbits="16">
<prepatterns>
<data>0x2000804e </data> <!-- BLR -->
<data>......00 0x.. 0x.. 010010.. </data> <!-- B xxxxx -->
</prepatterns>
<postpatterns>
<data>.....000 11...... 00100001 10010100 </data> <!-- 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/>
</postpatterns>
</patternpairs>
<patternpairs totalbits="32" postbits="16">
<prepatterns>
<data> ......00 0x.. 0x.. 010010.. </data> <!-- B xxxxx -->
</prepatterns>
<postpatterns>
<data>.....000 11...... 00100001 10010100 10100110 00000010 ...01000 011111.. </data> <!-- STWU r1,xx(r1); MFSPR rx,lr -->
<data>.....000 11...... 00100001 10010100 0x........ 10100110 00000010 ...01000 011111.. </data> <!-- STWU r1,xx(r1); xxx_instr; MFSPR rx,lr -->
<data>.....000 11...... 00100001 10010100 0x........ 0x........ 10100110 00000010 ...01000 011111.. </data> <!-- STWU r1,xx(r1); xxx_instr; xxx_instr; MFSPR rx,lr -->
<data>0x780b2c7c ........ ........ 0x21 0x38 0x00008191 </data> <!-- or r12,r1,r1; stw r12,0x0(r1) -->
<codeboundary /> <!-- it is at least code -->
<possiblefuncstart/>
</postpatterns>
</patternpairs>
<pattern>
<data>.....000 11...... 00100001 10010100 10100110 00000010 ...01000 011111.. </data> <!-- STWU r1,xx(r1); MFSPR rx,lr -->
<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 -->
</pattern>
</patternlist>

View File

@@ -2,4 +2,7 @@
<language id="PowerPC:BE:*:*">
<patternfile>PPC_BE_patterns.xml</patternfile>
</language>
</patternconstraints>
<language id="PowerPC:LE:*:*">
<patternfile>PPC_LE_patterns.xml</patternfile>
</language>
</patternconstraints>

View File

@@ -29,6 +29,7 @@ import ghidra.program.model.address.AddressSet;
import ghidra.program.model.data.DWordDataType;
import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.symbol.SourceType;
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.test.TestEnv;
@@ -208,4 +209,55 @@ public class CreateFunctionThunkTest extends AbstractGhidraHeadedIntegrationTest
assertEquals(true, isThunk.isThunk());
assertEquals("thunker", isThunk.getName());
}
/**
* Tests that the Function start analyzer will create a thunk given the thunk tag on a matching function
* Tests that constant propagation creates a reference using the callfixup value in LR
*
*/
@Test
public void testPPCblrlThunk() throws Exception {
builder = new ProgramBuilder("thunk", ProgramBuilder._PPC_32);
/**
* bl __get_pc_thunk_lr
* mfspr r30,LR
* lbz r3,0x0(r30)
* blr
*/
builder.setBytes("0x00002000", "42 80 00 31 7f c8 02 a6 88 1e 00 00 4e 80 00 20");
builder.disassemble("0x00002000", 27, true);
/**
* blrl
* lbz r12,0x0(r10)
* blr
*/
builder.setBytes("0x0002030", "4e 80 00 21 89 8a 00 00 4e 80 00 20");
builder.disassemble("0x0002030", 27, true);
builder.createFunction("0x0002000");
builder.createFunction("0x0002030");
program = builder.getProgram();
analyze();
Instruction instruction = program.getListing().getInstructionAt(builder.addr(0x2008));
assertNotNull(instruction);
Reference[] referencesFrom = instruction.getReferencesFrom();
// Thunk will set a value in LR that is not normal from the assumed return of a function
// used to calculate a constant reference
// TODO: There is a left-over BAD reference. Need to clean references on re-analysis
assertEquals(0x2034L, referencesFrom[1].getToAddress().getOffset());
Function thunker = program.getFunctionManager().getFunctionAt(builder.addr(0x0002030));
assertEquals("__get_pc_thunk_lr", thunker.getName());
assertEquals("get_pc_thunk_lr", thunker.getCallFixup());
}
}