@@ -369,7 +369,7 @@ def __init__(self, panda):
369
369
regnames = ["X0" , "X1" , "X2" , "X3" , "X4" , "X5" , "X6" , "X7" ,
370
370
"XR" , "X9" , "X10" , "X11" , "X12" , "X13" , "X14" ,
371
371
"X15" , "IP0" , "IP1" , "PR" , "X19" , "X20" , "X21" ,
372
- "X22" , "X23" , "X24" , "X25" , "X26" , "X27" , "X27" ,
372
+ "X22" , "X23" , "X24" , "X25" , "X26" , "X27" ,
373
373
"X28" , "FP" , "LR" , "SP" ]
374
374
375
375
self .reg_sp = regnames .index ("SP" )
@@ -601,6 +601,7 @@ def set_retval(self, cpu, val, convention='default', failure=False):
601
601
602
602
return super ().set_retval (cpu , val , convention )
603
603
604
+
604
605
class Mips64Arch (MipsArch ):
605
606
'''
606
607
Register names and accessors for MIPS64. Inherits from MipsArch for everything
@@ -629,67 +630,71 @@ def __init__(self, panda):
629
630
# note names must be stored uppercase for get/set reg to work case-insensitively
630
631
self .registers = {regnames [idx ].upper (): idx for idx in range (len (regnames )) }
631
632
632
- class X86Arch (PandaArch ):
633
+ class PowerPCArch (PandaArch ):
633
634
'''
634
- Register names and accessors for x86
635
+ Register names and accessors for ppc
635
636
'''
636
-
637
- def __init__ (self , panda ):
637
+ def __init__ (self , panda ):
638
638
super ().__init__ (panda )
639
- regnames = ['EAX' , 'ECX' , 'EDX' , 'EBX' , 'ESP' , 'EBP' , 'ESI' , 'EDI' ]
640
- # XXX Note order is A C D B, because that's how qemu does it . See target/i386/cpu.h
641
-
642
- # Note we don't set self.call_conventions because stack-based arg get/set is
643
- # not yet supported
644
- self .reg_retval = {"default" : "EAX" ,
645
- "syscall" : "EAX" ,
646
- "linux_kernel" : "EAX" }
647
-
648
- self .call_conventions = {"cdecl" : [f"stack_{ x } " for x in range (20 )], # 20: arbitrary but big
649
- "syscall" : ["EAX" , "EBX" , "ECX" , "EDX" , "ESI" , "EDI" , "EBP" ],
650
- "linux_kernel" : ["EAX" , "EDX" , "ECX" , "stack_3" , "stack_4" , "stack_5" , "stack_6" ]}
651
- self .call_conventions ['default' ] = self .call_conventions ['cdecl' ]
652
-
653
- self .reg_sp = regnames .index ('ESP' )
654
- self .registers = {regnames [idx ]: idx for idx in range (len (regnames )) }
655
-
639
+ regnames = ["r0" , "sp" , "r2" , "r3" , "r4" , "r5" , "r6" , "r7" , "r8" , "r9" , "r10" , "r11" ,
640
+ "r12" , "r13" , "r14" , "r15" , "r16" , "r17" , "r18" , "r19" , "r20" , "r21" , "r22" ,
641
+ "r23" , "r24" , "r25" , "r26" , "r27" , "r28" , "r29" , "r30" , "r31" ]
642
+ self .reg_sp = regnames .index ('sp' )
643
+ self .registers = {regnames [idx ].upper (): idx for idx in range (len (regnames )) }
644
+ self .registers_crf = ["CR0" , "CR1" , "CR2" , "CR3" , "CR4" , "CR5" , "CR6" , "CR7" ]
656
645
657
646
def get_pc (self , cpu ):
658
647
'''
659
- Overloaded function to return the x86 current program counter
648
+ Overloaded function to return the ppc current program counter
660
649
'''
661
- return cpu .env_ptr .eip
650
+ return cpu .env_ptr .nip
662
651
663
652
def set_pc (self , cpu , val ):
664
653
'''
665
- Overloaded function to set the x86 program counter
654
+ Overloaded function to set the ppc program counter
666
655
'''
667
- cpu .env_ptr .eip = val
656
+ cpu .env_ptr .nip = val
668
657
669
658
def _get_reg_val (self , cpu , reg ):
670
659
'''
671
- Return an x86 register
660
+ Return a ppc register
672
661
'''
673
- return cpu .env_ptr .regs [reg ]
662
+ return cpu .env_ptr .gpr [reg ]
674
663
675
664
def _set_reg_val (self , cpu , reg , val ):
676
665
'''
677
- Set an x86 register
666
+ Set an x86_64 register
678
667
'''
679
- cpu .env_ptr .regs [reg ] = val
668
+ cpu .env_ptr .gpr [reg ] = val
669
+
670
+ def get_reg (self , cpu , reg ):
671
+
672
+ reg = reg .upper ()
673
+ env = cpu .env_ptr
674
+ if reg == "LR" :
675
+ return env .lr
676
+ elif reg == "CTR" :
677
+ return env .ctr
678
+ elif reg in self .registers_crf :
679
+ return env .crf [self .registers_crf .index (reg )]
680
+ else :
681
+ return super ().get_reg (cpu , reg )
682
+
683
+
684
+ def set_reg (self , cpu , reg , val ):
685
+ reg = reg .upper ()
686
+ env = cpu .env_ptr
687
+
688
+ if reg == "LR" :
689
+ env .lr = val
690
+ elif reg == "CTR" :
691
+ env .ctr = val
692
+ elif reg in self .registers_crf :
693
+ env .crf [self .registers_crf .index (reg )] = val
694
+ else :
695
+ super ().set_reg (cpu , reg , val )
680
696
681
- def get_return_value (self , cpu ):
682
- '''
683
- .. Deprecated:: use get_retval
684
- '''
685
- return self .get_retval (cpu )
686
697
687
- def get_return_address (self ,cpu ):
688
- '''
689
- looks up where ret will go
690
- '''
691
- esp = self .get_reg (cpu ,"ESP" )
692
- return self .panda .virtual_memory_read (cpu ,esp ,4 ,fmt = 'int' )
693
698
694
699
class X86_64Arch (PandaArch ):
695
700
'''
@@ -722,6 +727,7 @@ def __init__(self, panda):
722
727
self .reg_names_short = ['AX' , 'CX' , 'DX' , 'BX' , 'SP' , 'BP' , 'SI' , 'DI' ]
723
728
self .reg_names_byte = ['AL' , 'CL' , 'DL' , 'BL' , 'AH' , 'CH' , 'DH' , 'BH' ]
724
729
self .seg_names = ['ES' , 'CS' , 'SS' , 'DS' , 'FS' , 'GS' ]
730
+ self .reg_names_mmr = ['LDT' , 'TR' , 'GDT' , 'IDT' ]
725
731
726
732
def _get_segment_register (self , env , seg_name ):
727
733
seg_idx = self .seg_names .index (seg_name )
@@ -765,6 +771,20 @@ def set_pc(self, cpu, val):
765
771
'''
766
772
cpu .env_ptr .eip = val
767
773
774
+ def _get_mmr_val (self , cpu , reg ):
775
+ reg = reg .lower ()
776
+ sc = getattr (cpu .env_ptr , reg )
777
+ return (sc .selector , sc .base , sc .limit , sc .flags )
778
+
779
+ def _set_mmr_val (self , cpu , reg , val ):
780
+ reg = reg .lower ()
781
+ selector , base , limit , flags = val
782
+ sc = getattr (cpu .env_ptr , reg )
783
+ sc .selector = selector
784
+ sc .base = base
785
+ sc .limit = limit
786
+ sc .flags = flags
787
+
768
788
def _get_reg_val (self , cpu , reg ):
769
789
'''
770
790
Return an x86_64 register
@@ -802,8 +822,12 @@ def get_reg(self, cpu, reg):
802
822
803
823
reg = reg .upper ()
804
824
env = cpu .env_ptr
825
+ if reg in self .reg_names_mmr :
826
+ return self ._get_mmr_val (cpu , reg )
805
827
if reg in self .seg_names :
806
828
return self ._get_segment_register (env , reg )
829
+ elif reg in ['EFLAGS' , 'RFLAGS' ]:
830
+ return env .eflags
807
831
elif reg in ['RIP' , 'PC' , 'EIP' ]:
808
832
pc = self .get_pc (cpu ) # changes reg to 'IP' and re-calls this
809
833
if reg == 'EIP' :
@@ -856,13 +880,17 @@ def set_reg(self, cpu, reg, val):
856
880
reg = reg .upper ()
857
881
env = cpu .env_ptr
858
882
859
- if reg in ['ES' , 'CS' , 'SS' , 'DS' , 'FS' , 'GS' ]:
883
+ if reg in self .reg_names_mmr :
884
+ return self ._set_mmr_val (cpu , reg , val )
885
+ elif reg in self .seg_names :
860
886
self ._set_segment_register (env , reg , val )
887
+ elif reg in ['EFLAGS' , 'RFLAGS' ]:
888
+ env .eflags = val
861
889
elif reg in ['RIP' , 'PC' ]:
862
890
return self .set_pc (cpu , val ) # changes reg to 'IP' and re-calls this
863
891
elif reg .startswith ('XMM' ):
864
- # env.xmm_regs[int(reg[3:])] = val
865
- raise NotImplementedError ("XMM registers unsupported" )
892
+ env .xmm_regs [int (reg [3 :])] = val
893
+ # raise NotImplementedError("XMM registers unsupported")
866
894
elif reg .startswith ('MM' ):
867
895
raise NotImplementedError ("MM registers unsupported" )
868
896
elif reg .startswith ('YMM' ):
@@ -890,3 +918,28 @@ def set_reg(self, cpu, reg, val):
890
918
self ._set_general_purpose_register (env , reg , val , mask )
891
919
else :
892
920
super ().set_reg (cpu , reg , val )
921
+
922
+
923
+ class X86Arch (X86_64Arch ):
924
+ '''
925
+ Register names and accessors for x86
926
+ '''
927
+
928
+ def __init__ (self , panda ):
929
+ super ().__init__ (panda )
930
+ regnames = ['EAX' , 'ECX' , 'EDX' , 'EBX' , 'ESP' , 'EBP' , 'ESI' , 'EDI' ]
931
+ # XXX Note order is A C D B, because that's how qemu does it . See target/i386/cpu.h
932
+
933
+ # Note we don't set self.call_conventions because stack-based arg get/set is
934
+ # not yet supported
935
+ self .reg_retval = {"default" : "EAX" ,
936
+ "syscall" : "EAX" ,
937
+ "linux_kernel" : "EAX" }
938
+
939
+ self .call_conventions = {"cdecl" : [f"stack_{ x } " for x in range (20 )], # 20: arbitrary but big
940
+ "syscall" : ["EAX" , "EBX" , "ECX" , "EDX" , "ESI" , "EDI" , "EBP" ],
941
+ "linux_kernel" : ["EAX" , "EDX" , "ECX" , "stack_3" , "stack_4" , "stack_5" , "stack_6" ]}
942
+ self .call_conventions ['default' ] = self .call_conventions ['cdecl' ]
943
+
944
+ self .reg_sp = regnames .index ('ESP' )
945
+ self .registers = {regnames [idx ]: idx for idx in range (len (regnames )) }
0 commit comments