@@ -281,7 +281,6 @@ class PowerpcArchitecture: public Architecture
281281{
282282 private:
283283 BNEndianness endian;
284- int cs_mode_local;
285284 size_t addressSize;
286285
287286 /* this can maybe be moved to the API later */
@@ -298,11 +297,10 @@ class PowerpcArchitecture: public Architecture
298297 public:
299298
300299 /* initialization list */
301- PowerpcArchitecture (const char * name, BNEndianness endian_, size_t addressSize_=4 , int cs_mode_= 0 ): Architecture(name)
300+ PowerpcArchitecture (const char * name, BNEndianness endian_, size_t addressSize_=4 ): Architecture(name)
302301 {
303302 endian = endian_;
304303 addressSize = addressSize_;
305- cs_mode_local = cs_mode_;
306304 }
307305
308306 /* ************************************************************************/
@@ -358,13 +356,13 @@ class PowerpcArchitecture: public Architecture
358356 return false ;
359357 }
360358
361- if (DoesQualifyForLocalDisassembly (data, endian == BigEndian )) {
359+ if (DoesQualifyForLocalDisassembly (data)) {
362360 result.length = 4 ;
363361 return true ;
364362 }
365363
366364 /* decompose the instruction to get branch info */
367- if (powerpc_decompose (data, 4 , (uint32_t )addr, endian == LittleEndian, &res, GetAddressSize () == 8 , cs_mode_local )) {
365+ if (powerpc_decompose (data, 4 , (uint32_t )addr, endian == LittleEndian, &res, GetAddressSize () == 8 )) {
368366 MYLOG (" ERROR: powerpc_decompose()\n " );
369367 return false ;
370368 }
@@ -457,56 +455,149 @@ class PowerpcArchitecture: public Architecture
457455 return true ;
458456 }
459457
460- bool PrintLocalDisassembly (const uint8_t *data, uint64_t addr, size_t &len, vector<InstructionTextToken> &result, decomp_result* res )
458+ bool DoesQualifyForLocalDisassembly (const uint8_t *data)
461459 {
462- (void )addr;
463- char buf[16 ];
464- uint32_t local_op = PPC_INS_INVALID;
460+ uint32_t insword = *(uint32_t *)data;
461+ if (endian == BigEndian)
462+ insword = bswap32 (insword);
463+
464+ // 111111xxx00xxxxxxxxxx00001000000 <- fcmpo
465+ uint32_t tmp = insword & 0xFC6007FF ;
466+ if (tmp==0xFC000040 )
467+ return true ;
468+ // 111100xxxxxxxxxxxxxxx00111010xxx <- xxpermr
469+ if ((insword & 0xFC0007F8 ) == 0xF00001D0 )
470+ return true ;
471+ // 000100xxxxxxxxxxxxxxxxxxx000110x <- psq_lx
472+ // 000100xxxxxxxxxxxxxxxxxxx000111x <- psq_stx
473+ // 000100xxxxxxxxxxxxxxxxxxx100110x <- psq_lux
474+ // 000100xxxxxxxxxxxxxxxxxxx100111x <- psq_stux
475+ tmp = insword & 0xFC00007E ;
476+ if (tmp==0x1000000C || tmp==0x1000000E || tmp==0x1000004C || tmp==0x1000004E )
477+ return true ;
478+ // 000100xxxxxxxxxx00000xxxxx011000 <- ps_muls0
479+ // 000100xxxxxxxxxx00000xxxxx011001 <- ps_muls0.
480+ // 000100xxxxxxxxxx00000xxxxx011010 <- ps_muls1
481+ // 000100xxxxxxxxxx00000xxxxx011011 <- ps_muls1.
482+ tmp = insword & 0xFC00F83F ;
483+ if (tmp==0x10000018 || tmp==0x10000019 || tmp==0x1000001A || tmp==0x1000001B )
484+ return true ;
485+
486+ return false ;
487+ }
465488
466- struct cs_detail *detail = 0 ;
467- struct cs_ppc *ppc = 0 ;
468- struct cs_insn *insn = &(res-> insn ) ;
489+ bool PerformLocalDisassembly ( const uint8_t *data, uint64_t addr, size_t &len, vector<InstructionTextToken> &result)
490+ {
491+ ( void )addr ;
469492
470- detail = &(res->detail );
471- ppc = &(detail->ppc );
493+ if (len < 4 ) return false ;
494+ uint32_t insword = *(uint32_t *)data;
495+ if (endian == BigEndian)
496+ insword = bswap32 (insword);
472497
473- if (len < 4 )
474- return false ;
475498 len = 4 ;
476499
477- local_op = DoesQualifyForLocalDisassembly (data, endian == BigEndian);
478- PerformLocalDisassembly (data, addr, len, res, endian == BigEndian);
500+ char buf[16 ];
479501
480- switch (local_op)
481- {
482- case PPC_INS_BN_FCMPO:
483- result.emplace_back (InstructionToken, insn-> mnemonic );
502+ // 111111AAA00BBBBBCCCCC00001000000 "fcmpo crA,fB,fC"
503+ uint32_t tmp = insword & 0xFC6007FF ;
504+ if (tmp== 0xFC000040 ) {
505+ result.emplace_back (InstructionToken, " fcmpo " );
484506 result.emplace_back (TextToken, " " );
485- snprintf (buf, sizeof (buf), " cr%d" , ppc-> operands [ 0 ]. reg - PPC_REG_CR0 );
507+ snprintf (buf, sizeof (buf), " cr%d" , (insword >> 23 ) & 7 );
486508 result.emplace_back (RegisterToken, buf);
487509 result.emplace_back (OperandSeparatorToken, " , " );
488- snprintf (buf, sizeof (buf), " f%d" , ppc-> operands [ 1 ]. reg - PPC_REG_F0 );
510+ snprintf (buf, sizeof (buf), " f%d" , (insword >> 16 ) & 31 );
489511 result.emplace_back (RegisterToken, buf);
490512 result.emplace_back (OperandSeparatorToken, " , " );
491- snprintf (buf, sizeof (buf), " f%d" , ppc-> operands [ 2 ]. reg - PPC_REG_F0 );
513+ snprintf (buf, sizeof (buf), " f%d" , (insword >> 11 ) & 31 );
492514 result.emplace_back (RegisterToken, buf);
493- break ;
494- case PPC_INS_BN_XXPERMR:
495- result.emplace_back (InstructionToken, insn->mnemonic );
515+ return true ;
516+ }
517+
518+ // 111100AAAAABBBBBCCCCC00011010BCA "xxpermr vsA,vsB,vsC"
519+ if ((insword & 0xFC0007F8 )==0xF00001D0 ) {
520+ int a = ((insword & 0x3E00000 )>>21 )|((insword & 0x1 )<<5 );
521+ int b = ((insword & 0x1F0000 )>>16 )|((insword & 0x4 )<<3 );
522+ int c = ((insword & 0xF800 )>>11 )|((insword & 0x2 )<<4 );
523+ result.emplace_back (InstructionToken, " xxpermr" );
496524 result.emplace_back (TextToken, " " );
497- snprintf (buf, sizeof (buf), " vs%d" , ppc-> operands [ 0 ]. reg - PPC_REG_VS0 );
525+ snprintf (buf, sizeof (buf), " vs%d" , a );
498526 result.emplace_back (RegisterToken, buf);
499527 result.emplace_back (OperandSeparatorToken, " , " );
500- snprintf (buf, sizeof (buf), " vs%d" , ppc-> operands [ 1 ]. reg - PPC_REG_VS0 );
528+ snprintf (buf, sizeof (buf), " vs%d" , b );
501529 result.emplace_back (RegisterToken, buf);
502530 result.emplace_back (OperandSeparatorToken, " , " );
503- snprintf (buf, sizeof (buf), " vs%d" , ppc-> operands [ 2 ]. reg - PPC_REG_VS0 );
531+ snprintf (buf, sizeof (buf), " vs%d" , c );
504532 result.emplace_back (RegisterToken, buf);
505- break ;
506- default :
507- return false ;
533+ return true ;
508534 }
509- return true ;
535+
536+ // 000100AAAAABBBBBCCCCCDEEE000110x psq_lx FREG,GPR,GPR,NUM,NUM
537+ // 000100AAAAABBBBBCCCCCDEEE000111x psq_stx FREG,GPR,GPR,NUM,NUM
538+ // 000100AAAAABBBBBCCCCCDEEE100110x psq_lux FREG,GPR,GPR,NUM,NUM
539+ // 000100AAAAABBBBBCCCCCDEEE100111x psq_stux FREG,GPR,GPR,NUM,NUM
540+ tmp = insword & 0xFC00007E ;
541+ if (tmp==0x1000000C || tmp==0x1000000E || tmp==0x1000004C || tmp==0x1000004E ) {
542+ switch (tmp) {
543+ case 0x1000000C :
544+ result.emplace_back (InstructionToken, " psq_lx" );
545+ result.emplace_back (TextToken, " " );
546+ break ;
547+ case 0x1000000E : result.emplace_back (InstructionToken, " psq_stx" );
548+ result.emplace_back (TextToken, " " );
549+ break ;
550+ case 0x1000004C : result.emplace_back (InstructionToken, " psq_lux" );
551+ result.emplace_back (TextToken, " " );
552+ break ;
553+ case 0x1000004E : result.emplace_back (InstructionToken, " psq_stux" );
554+ result.emplace_back (TextToken, " " );
555+ break ;
556+ }
557+ snprintf (buf, sizeof (buf), " f%d" , (insword & 0x3E00000 ) >> 21 );
558+ result.emplace_back (RegisterToken, buf);
559+ result.emplace_back (OperandSeparatorToken, " , " );
560+ snprintf (buf, sizeof (buf), " r%d" , (insword & 0x1F0000 ) >> 16 );
561+ result.emplace_back (RegisterToken, buf);
562+ result.emplace_back (OperandSeparatorToken, " , " );
563+ snprintf (buf, sizeof (buf), " r%d" , (insword & 0xF800 ) >> 11 );
564+ result.emplace_back (RegisterToken, buf);
565+ result.emplace_back (OperandSeparatorToken, " , " );
566+ tmp = (insword & 0x400 )>>10 ;
567+ snprintf (buf, sizeof (buf), " %d" , tmp);
568+ result.emplace_back (IntegerToken, buf, tmp, 1 );
569+ result.emplace_back (OperandSeparatorToken, " , " );
570+ tmp = (insword & 0x380 )>>7 ;
571+ snprintf (buf, sizeof (buf), " %d" , tmp);
572+ result.emplace_back (IntegerToken, buf, tmp, 1 );
573+ return true ;
574+ }
575+
576+ // 000100AAAAABBBBB00000CCCCC011000 ps_muls0 FREG,FREG,FREG
577+ // 000100AAAAABBBBB00000CCCCC011001 ps_muls0. FREG,FREG,FREG
578+ // 000100AAAAABBBBB00000CCCCC011010 ps_muls1 FREG,FREG,FREG
579+ // 000100AAAAABBBBB00000CCCCC011011 ps_muls1. FREG,FREG,FREG
580+ tmp = insword & 0xFC00F83F ;
581+ if (tmp==0x10000018 || tmp==0x10000019 || tmp==0x1000001A || tmp==0x1000001B ) {
582+ switch (tmp) {
583+ case 0x10000018 : result.emplace_back (InstructionToken, " ps_muls0" ); break ;
584+ case 0x10000019 : result.emplace_back (InstructionToken, " ps_muls0." ); break ;
585+ case 0x1000001A : result.emplace_back (InstructionToken, " ps_muls1" ); break ;
586+ case 0x1000001B : result.emplace_back (InstructionToken, " ps_muls1." ); break ;
587+ }
588+ result.emplace_back (TextToken, " " );
589+ snprintf (buf, sizeof (buf), " f%d" , (insword & 0x3E00000 ) >> 21 );
590+ result.emplace_back (RegisterToken, buf);
591+ result.emplace_back (OperandSeparatorToken, " , " );
592+ snprintf (buf, sizeof (buf), " f%d" , (insword & 0x1F0000 ) >> 16 );
593+ result.emplace_back (RegisterToken, buf);
594+ result.emplace_back (OperandSeparatorToken, " , " );
595+ snprintf (buf, sizeof (buf), " f%d" , (insword & 0x7C0 ) >> 6 );
596+ result.emplace_back (RegisterToken, buf);
597+ return true ;
598+ }
599+
600+ return false ;
510601 }
511602
512603 /* populate the vector result with InstructionTextToken
@@ -530,12 +621,10 @@ class PowerpcArchitecture: public Architecture
530621 goto cleanup;
531622 }
532623
533- if (DoesQualifyForLocalDisassembly (data, endian == BigEndian))
534- {
535- // PerformLocalDisassembly(data, addr, len, &res, endian == BigEndian);
536- return PrintLocalDisassembly (data, addr, len, result, &res);
537- }
538- if (powerpc_decompose (data, 4 , (uint32_t )addr, endian == LittleEndian, &res, GetAddressSize () == 8 , cs_mode_local)) {
624+ if (DoesQualifyForLocalDisassembly (data))
625+ return PerformLocalDisassembly (data, addr, len, result);
626+
627+ if (powerpc_decompose (data, 4 , (uint32_t )addr, endian == LittleEndian, &res, GetAddressSize () == 8 )) {
539628 MYLOG (" ERROR: powerpc_decompose()\n " );
540629 goto cleanup;
541630 }
@@ -642,7 +731,6 @@ class PowerpcArchitecture: public Architecture
642731 virtual bool GetInstructionLowLevelIL (const uint8_t * data, uint64_t addr, size_t & len, LowLevelILFunction& il) override
643732 {
644733 bool rc = false ;
645- struct decomp_result res = {0 };
646734
647735 if (len < 4 ) {
648736 MYLOG (" ERROR: need at least 4 bytes\n " );
@@ -653,16 +741,21 @@ class PowerpcArchitecture: public Architecture
653741 // MYLOG("%s(data, 0x%llX, 0x%zX, il)\n", __func__, addr, len);
654742 // }
655743
656- if (DoesQualifyForLocalDisassembly (data, endian == BigEndian)) {
657- PerformLocalDisassembly (data, addr, len, &res, endian == BigEndian);
744+ struct decomp_result res;
745+
746+ if (DoesQualifyForLocalDisassembly (data)) {
747+ il.AddInstruction (il.Unimplemented ());
748+ rc = true ;
749+ len = 4 ;
750+ goto cleanup;
658751 }
659- else if (powerpc_decompose (data, 4 , (uint32_t )addr, endian == LittleEndian, &res, GetAddressSize () == 8 , cs_mode_local)) {
752+
753+ if (powerpc_decompose (data, 4 , (uint32_t )addr, endian == LittleEndian, &res, GetAddressSize () == 8 )) {
660754 MYLOG (" ERROR: powerpc_decompose()\n " );
661755 il.AddInstruction (il.Undefined ());
662756 goto cleanup;
663757 }
664758
665- getil:
666759 rc = GetLowLevelILForPPCInstruction (this , il, data, addr, &res, endian == LittleEndian);
667760 len = 4 ;
668761
@@ -714,7 +807,7 @@ class PowerpcArchitecture: public Architecture
714807 }
715808
716809 auto liftOps = [&]() {
717- if (( op == LLIL_SUB) || (op == LLIL_FSUB) )
810+ if (op == LLIL_SUB)
718811 {
719812 left = il.GetExprForRegisterOrConstant (operands[0 ], size);
720813 right = il.GetExprForRegisterOrConstant (operands[1 ], size);
@@ -831,7 +924,7 @@ class PowerpcArchitecture: public Architecture
831924
832925 virtual string GetRegisterName (uint32_t regId) override
833926 {
834- const char *result = powerpc_reg_to_str (regId, cs_mode_local );
927+ const char *result = powerpc_reg_to_str (regId);
835928
836929 if (result == NULL )
837930 result = " " ;
@@ -2380,15 +2473,6 @@ extern "C"
23802473 Architecture* ppc = new PowerpcArchitecture (" ppc" , BigEndian);
23812474 Architecture::Register (ppc);
23822475
2383- Architecture* ppc_qpx = new PowerpcArchitecture (" ppc_qpx" , BigEndian, 4 , CS_MODE_QPX);
2384- Architecture::Register (ppc_qpx);
2385-
2386- Architecture* ppc_spe = new PowerpcArchitecture (" ppc_spe" , BigEndian, 4 , CS_MODE_SPE);
2387- Architecture::Register (ppc_spe);
2388-
2389- Architecture* ppc_ps = new PowerpcArchitecture (" ppc_ps" , BigEndian, 4 , CS_MODE_PS);
2390- Architecture::Register (ppc_ps);
2391-
23922476 Architecture* ppc64 = new PowerpcArchitecture (" ppc64" , BigEndian, 8 );
23932477 Architecture::Register (ppc64);
23942478
@@ -2403,19 +2487,10 @@ extern "C"
24032487 conv = new PpcSvr4CallingConvention (ppc);
24042488 ppc->RegisterCallingConvention (conv);
24052489 ppc->SetDefaultCallingConvention (conv);
2406- ppc_qpx->RegisterCallingConvention (conv);
2407- ppc_qpx->SetDefaultCallingConvention (conv);
2408- ppc_spe->RegisterCallingConvention (conv);
2409- ppc_spe->SetDefaultCallingConvention (conv);
2410- ppc_ps->RegisterCallingConvention (conv);
2411- ppc_ps->SetDefaultCallingConvention (conv);
24122490 ppc64->RegisterCallingConvention (conv);
24132491 ppc64->SetDefaultCallingConvention (conv);
24142492 conv = new PpcLinuxSyscallCallingConvention (ppc);
24152493 ppc->RegisterCallingConvention (conv);
2416- ppc_qpx->RegisterCallingConvention (conv);
2417- ppc_spe->RegisterCallingConvention (conv);
2418- ppc_ps->RegisterCallingConvention (conv);
24192494 ppc64->RegisterCallingConvention (conv);
24202495
24212496 conv = new PpcSvr4CallingConvention (ppc_le);
@@ -2429,15 +2504,9 @@ extern "C"
24292504
24302505 /* function recognizer */
24312506 ppc->RegisterFunctionRecognizer (new PpcImportedFunctionRecognizer ());
2432- ppc_qpx->RegisterFunctionRecognizer (new PpcImportedFunctionRecognizer ());
2433- ppc_spe->RegisterFunctionRecognizer (new PpcImportedFunctionRecognizer ());
2434- ppc_ps->RegisterFunctionRecognizer (new PpcImportedFunctionRecognizer ());
24352507 ppc_le->RegisterFunctionRecognizer (new PpcImportedFunctionRecognizer ());
24362508
24372509 ppc->RegisterRelocationHandler (" ELF" , new PpcElfRelocationHandler ());
2438- ppc_qpx->RegisterRelocationHandler (" ELF" , new PpcElfRelocationHandler ());
2439- ppc_spe->RegisterRelocationHandler (" ELF" , new PpcElfRelocationHandler ());
2440- ppc_ps->RegisterRelocationHandler (" ELF" , new PpcElfRelocationHandler ());
24412510 ppc_le->RegisterRelocationHandler (" ELF" , new PpcElfRelocationHandler ());
24422511 ppc_le->RegisterRelocationHandler (" Mach-O" , new PpcMachoRelocationHandler ());
24432512 /* call the STATIC RegisterArchitecture with "Mach-O"
@@ -2471,13 +2540,6 @@ extern "C"
24712540 ppc /* the architecture */
24722541 );
24732542
2474- BinaryViewType::RegisterArchitecture (
2475- " ELF" , /* name of the binary view type */
2476- EM_PPC, /* id (key in m_arch map) */
2477- BigEndian,
2478- ppc_ps /* the architecture */
2479- );
2480-
24812543 BinaryViewType::RegisterArchitecture (
24822544 " ELF" , /* name of the binary view type */
24832545 EM_PPC64, /* id (key in m_arch map) */
0 commit comments