Skip to content

Commit 9341079

Browse files
author
noone
committed
Add notion of instruction length
1 parent 1b43a12 commit 9341079

File tree

5 files changed

+54
-35
lines changed

5 files changed

+54
-35
lines changed

arch/powerpc/arch_ppc.cpp

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,22 @@ class PowerpcArchitecture: public Architecture
340340

341341
bool FillInstruction(Instruction* instruction, const uint8_t* data, size_t length, uint64_t address)
342342
{
343-
uint32_t word32 = *(const uint32_t *) data;
343+
switch (length)
344+
{
345+
case 4:
346+
{
347+
uint32_t word32 = *(const uint32_t *) data;
344348

345-
if (endian == BigEndian)
346-
word32 = bswap32(word32);
349+
if (endian == BigEndian)
350+
word32 = bswap32(word32);
347351

348-
return Decompose(instruction, word32, address, decodeFlags);
352+
return Decompose32(instruction, word32, address, decodeFlags);
353+
}
354+
355+
default:
356+
MYLOG("FillInstruction: unrecognized length %d", length);
357+
return false;
358+
}
349359
}
350360

351361
/* think "GetInstructionBranchBehavior()"
@@ -361,17 +371,17 @@ class PowerpcArchitecture: public Architecture
361371
virtual bool GetInstructionInfo(const uint8_t* data, uint64_t addr,
362372
size_t maxLen, InstructionInfo& result) override
363373
{
364-
Instruction instruction;
365-
366-
if (maxLen < 4)
374+
size_t instructionLength = GetInstructionLength(data, maxLen, decodeFlags);
375+
if (instructionLength == 0)
367376
{
368-
MYLOG("ERROR: need at least 4 bytes\n");
377+
MYLOG("ERROR: not enough bytes for instruction\n");
369378
return false;
370379
}
371380

372-
result.length = 4;
381+
result.length = instructionLength;
373382

374-
if (!FillInstruction(&instruction, data, maxLen, addr))
383+
Instruction instruction;
384+
if (!FillInstruction(&instruction, data, instructionLength, addr))
375385
{
376386
MYLOG("ERROR: FillInstruction()\n");
377387
return false;
@@ -540,15 +550,15 @@ class PowerpcArchitecture: public Architecture
540550
const char* mnemonic = NULL;
541551

542552
//MYLOG("%s()\n", __func__);
543-
544-
if (len < 4)
553+
size_t instructionLength = GetInstructionLength(data, len, decodeFlags);
554+
if (instructionLength == 0)
545555
{
546-
MYLOG("ERROR: need at least 4 bytes\n");
556+
MYLOG("ERROR: not enough bytes for instruction\n");
547557
return false;
548558
}
549559

550-
len = 4;
551-
if (!FillInstruction(&instruction, data, len, addr))
560+
len = instructionLength;
561+
if (!FillInstruction(&instruction, data, instructionLength, addr))
552562
{
553563
MYLOG("ERROR: FillInstruction()\n");
554564
return false;
@@ -740,27 +750,24 @@ class PowerpcArchitecture: public Architecture
740750

741751
virtual bool GetInstructionLowLevelIL(const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il) override
742752
{
743-
Instruction instruction;
744-
bool rc = false;
745-
746-
if (len < 4)
753+
size_t instructionLength = GetInstructionLength(data, len, decodeFlags);
754+
if (instructionLength == 0)
747755
{
748-
MYLOG("ERROR: need at least 4 bytes\n");
749-
goto cleanup;
756+
MYLOG("ERROR: not enough bytes for instruction\n");
757+
return false;
750758
}
751759

752-
if (!FillInstruction(&instruction, data, len, addr))
760+
len = instructionLength;
761+
762+
Instruction instruction;
763+
if (!FillInstruction(&instruction, data, instructionLength, addr))
753764
{
754765
MYLOG("ERROR: FillInstruction()\n");
755766
il.AddInstruction(il.Undefined());
756-
goto cleanup;
767+
return false;
757768
}
758769

759-
rc = GetLowLevelILForPPCInstruction(this, il, &instruction, addr);
760-
len = 4;
761-
762-
cleanup:
763-
return rc;
770+
return GetLowLevelILForPPCInstruction(this, il, &instruction, addr);
764771
}
765772

766773
virtual size_t GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,

arch/powerpc/decode/decode.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@
99
// Implementations of the PowerPC^TM Architecture" by Freescale/NXP
1010
//
1111

12+
size_t GetInstructionLength(const uint8_t* data, size_t data_length, uint32_t decodeFlags)
13+
{
14+
(void)data;
15+
(void)data_length;
16+
(void)decodeFlags;
17+
18+
return 4;
19+
}
20+
1221
static InstructionId DecodeAltivec0x04(uint32_t word32, uint32_t decodeFlags)
1322
{
1423
uint32_t subop = word32 & 0x3f;
@@ -5429,7 +5438,7 @@ static InstructionId Decode0x3F(uint32_t word32, uint32_t flags)
54295438
return true;
54305439
}
54315440

5432-
static InstructionId Decode(uint32_t word32, uint32_t decodeFlags)
5441+
static InstructionId Decode32(uint32_t word32, uint32_t decodeFlags)
54335442
{
54345443
uint32_t a = GetA(word32);
54355444

@@ -5754,14 +5763,14 @@ static InstructionId Decode(uint32_t word32, uint32_t decodeFlags)
57545763
}
57555764
}
57565765

5757-
bool Decompose(Instruction* instruction, uint32_t word32, uint64_t address, uint32_t flags)
5766+
bool Decompose32(Instruction* instruction, uint32_t word32, uint64_t address, uint32_t flags)
57585767
{
57595768
memset(instruction, 0, sizeof *instruction);
57605769

5761-
instruction->id = Decode(word32, flags);
5770+
instruction->id = Decode32(word32, flags);
57625771
if (instruction->id == PPC_ID_INVALID)
57635772
return false;
57645773

5765-
FillOperands(instruction, word32, address);
5774+
FillOperands32(instruction, word32, address);
57665775
return true;
57675776
}

arch/powerpc/decode/decode.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1647,7 +1647,10 @@ extern "C" {
16471647
typedef struct Instruction Instruction;
16481648
#endif
16491649

1650-
bool Decompose(Instruction* instruction, uint32_t word32, uint64_t address, uint32_t flags);
1650+
// returns 0 if data_length is too small to tell
1651+
size_t GetInstructionLength(const uint8_t* data, size_t data_length, uint32_t flags);
1652+
1653+
bool Decompose32(Instruction* instruction, uint32_t word32, uint64_t address, uint32_t flags);
16511654
void FillBcxOperands(OperandsList* bcx, const Instruction* instruction);
16521655
void FillBcctrxOperands(OperandsList* bcctrx, const Instruction* instruction);
16531656
void FillBclrxOperands(OperandsList* bclrx, const Instruction* instruction);

arch/powerpc/decode/operands.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ static void PushAltivecVS(Instruction* instruction, uint32_t word32)
310310
PushRegister(instruction, PPC_OP_REG_AV_VS, AltivecVr(vs));
311311
}
312312

313-
void FillOperands(Instruction* instruction, uint32_t word32, uint64_t address)
313+
void FillOperands32(Instruction* instruction, uint32_t word32, uint64_t address)
314314
{
315315
switch (instruction->id)
316316
{

arch/powerpc/decode/priv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ uint32_t GetSH(uint32_t word32);
2424
uint32_t GetSH64(uint32_t word32);
2525
uint32_t GetMX64(uint32_t word32);
2626

27-
void FillOperands(Instruction* instruction, uint32_t word32, uint64_t address);
27+
void FillOperands32(Instruction* instruction, uint32_t word32, uint64_t address);

0 commit comments

Comments
 (0)