smallworld-re 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. smallworld/__init__.py +35 -0
  2. smallworld/analyses/__init__.py +14 -0
  3. smallworld/analyses/analysis.py +88 -0
  4. smallworld/analyses/code_coverage.py +31 -0
  5. smallworld/analyses/colorizer.py +682 -0
  6. smallworld/analyses/colorizer_summary.py +100 -0
  7. smallworld/analyses/field_detection/__init__.py +14 -0
  8. smallworld/analyses/field_detection/field_analysis.py +536 -0
  9. smallworld/analyses/field_detection/guards.py +26 -0
  10. smallworld/analyses/field_detection/hints.py +133 -0
  11. smallworld/analyses/field_detection/malloc.py +211 -0
  12. smallworld/analyses/forced_exec/__init__.py +3 -0
  13. smallworld/analyses/forced_exec/forced_exec.py +87 -0
  14. smallworld/analyses/underlays/__init__.py +4 -0
  15. smallworld/analyses/underlays/basic.py +13 -0
  16. smallworld/analyses/underlays/underlay.py +31 -0
  17. smallworld/analyses/unstable/__init__.py +4 -0
  18. smallworld/analyses/unstable/angr/__init__.py +0 -0
  19. smallworld/analyses/unstable/angr/base.py +12 -0
  20. smallworld/analyses/unstable/angr/divergence.py +274 -0
  21. smallworld/analyses/unstable/angr/model.py +383 -0
  22. smallworld/analyses/unstable/angr/nwbt.py +63 -0
  23. smallworld/analyses/unstable/angr/typedefs.py +170 -0
  24. smallworld/analyses/unstable/angr/utils.py +25 -0
  25. smallworld/analyses/unstable/angr/visitor.py +315 -0
  26. smallworld/analyses/unstable/angr_nwbt.py +106 -0
  27. smallworld/analyses/unstable/code_coverage.py +54 -0
  28. smallworld/analyses/unstable/code_reachable.py +44 -0
  29. smallworld/analyses/unstable/control_flow_tracer.py +71 -0
  30. smallworld/analyses/unstable/pointer_finder.py +90 -0
  31. smallworld/arch/__init__.py +0 -0
  32. smallworld/arch/aarch64_arch.py +286 -0
  33. smallworld/arch/amd64_arch.py +86 -0
  34. smallworld/arch/i386_arch.py +44 -0
  35. smallworld/emulators/__init__.py +14 -0
  36. smallworld/emulators/angr/__init__.py +7 -0
  37. smallworld/emulators/angr/angr.py +1652 -0
  38. smallworld/emulators/angr/default.py +15 -0
  39. smallworld/emulators/angr/exceptions.py +7 -0
  40. smallworld/emulators/angr/exploration/__init__.py +9 -0
  41. smallworld/emulators/angr/exploration/bounds.py +27 -0
  42. smallworld/emulators/angr/exploration/default.py +17 -0
  43. smallworld/emulators/angr/exploration/terminate.py +22 -0
  44. smallworld/emulators/angr/factory.py +55 -0
  45. smallworld/emulators/angr/machdefs/__init__.py +35 -0
  46. smallworld/emulators/angr/machdefs/aarch64.py +292 -0
  47. smallworld/emulators/angr/machdefs/amd64.py +192 -0
  48. smallworld/emulators/angr/machdefs/arm.py +387 -0
  49. smallworld/emulators/angr/machdefs/i386.py +221 -0
  50. smallworld/emulators/angr/machdefs/machdef.py +138 -0
  51. smallworld/emulators/angr/machdefs/mips.py +184 -0
  52. smallworld/emulators/angr/machdefs/mips64.py +189 -0
  53. smallworld/emulators/angr/machdefs/ppc.py +101 -0
  54. smallworld/emulators/angr/machdefs/riscv.py +261 -0
  55. smallworld/emulators/angr/machdefs/xtensa.py +255 -0
  56. smallworld/emulators/angr/memory/__init__.py +7 -0
  57. smallworld/emulators/angr/memory/default.py +10 -0
  58. smallworld/emulators/angr/memory/fixups.py +43 -0
  59. smallworld/emulators/angr/memory/memtrack.py +105 -0
  60. smallworld/emulators/angr/scratch.py +43 -0
  61. smallworld/emulators/angr/simos.py +53 -0
  62. smallworld/emulators/angr/utils.py +70 -0
  63. smallworld/emulators/emulator.py +1013 -0
  64. smallworld/emulators/hookable.py +252 -0
  65. smallworld/emulators/panda/__init__.py +5 -0
  66. smallworld/emulators/panda/machdefs/__init__.py +28 -0
  67. smallworld/emulators/panda/machdefs/aarch64.py +93 -0
  68. smallworld/emulators/panda/machdefs/amd64.py +71 -0
  69. smallworld/emulators/panda/machdefs/arm.py +89 -0
  70. smallworld/emulators/panda/machdefs/i386.py +36 -0
  71. smallworld/emulators/panda/machdefs/machdef.py +86 -0
  72. smallworld/emulators/panda/machdefs/mips.py +94 -0
  73. smallworld/emulators/panda/machdefs/mips64.py +91 -0
  74. smallworld/emulators/panda/machdefs/ppc.py +79 -0
  75. smallworld/emulators/panda/panda.py +575 -0
  76. smallworld/emulators/unicorn/__init__.py +13 -0
  77. smallworld/emulators/unicorn/machdefs/__init__.py +28 -0
  78. smallworld/emulators/unicorn/machdefs/aarch64.py +310 -0
  79. smallworld/emulators/unicorn/machdefs/amd64.py +326 -0
  80. smallworld/emulators/unicorn/machdefs/arm.py +321 -0
  81. smallworld/emulators/unicorn/machdefs/i386.py +137 -0
  82. smallworld/emulators/unicorn/machdefs/machdef.py +117 -0
  83. smallworld/emulators/unicorn/machdefs/mips.py +202 -0
  84. smallworld/emulators/unicorn/unicorn.py +684 -0
  85. smallworld/exceptions/__init__.py +5 -0
  86. smallworld/exceptions/exceptions.py +85 -0
  87. smallworld/exceptions/unstable/__init__.py +1 -0
  88. smallworld/exceptions/unstable/exceptions.py +25 -0
  89. smallworld/extern/__init__.py +4 -0
  90. smallworld/extern/ctypes.py +94 -0
  91. smallworld/extern/unstable/__init__.py +1 -0
  92. smallworld/extern/unstable/ghidra.py +129 -0
  93. smallworld/helpers.py +107 -0
  94. smallworld/hinting/__init__.py +8 -0
  95. smallworld/hinting/hinting.py +214 -0
  96. smallworld/hinting/hints.py +427 -0
  97. smallworld/hinting/unstable/__init__.py +2 -0
  98. smallworld/hinting/utils.py +19 -0
  99. smallworld/instructions/__init__.py +18 -0
  100. smallworld/instructions/aarch64.py +20 -0
  101. smallworld/instructions/arm.py +18 -0
  102. smallworld/instructions/bsid.py +67 -0
  103. smallworld/instructions/instructions.py +258 -0
  104. smallworld/instructions/mips.py +21 -0
  105. smallworld/instructions/x86.py +100 -0
  106. smallworld/logging.py +90 -0
  107. smallworld/platforms.py +95 -0
  108. smallworld/py.typed +0 -0
  109. smallworld/state/__init__.py +6 -0
  110. smallworld/state/cpus/__init__.py +32 -0
  111. smallworld/state/cpus/aarch64.py +563 -0
  112. smallworld/state/cpus/amd64.py +676 -0
  113. smallworld/state/cpus/arm.py +630 -0
  114. smallworld/state/cpus/cpu.py +71 -0
  115. smallworld/state/cpus/i386.py +239 -0
  116. smallworld/state/cpus/mips.py +374 -0
  117. smallworld/state/cpus/mips64.py +372 -0
  118. smallworld/state/cpus/powerpc.py +229 -0
  119. smallworld/state/cpus/riscv.py +357 -0
  120. smallworld/state/cpus/xtensa.py +80 -0
  121. smallworld/state/memory/__init__.py +7 -0
  122. smallworld/state/memory/code.py +70 -0
  123. smallworld/state/memory/elf/__init__.py +3 -0
  124. smallworld/state/memory/elf/elf.py +564 -0
  125. smallworld/state/memory/elf/rela/__init__.py +32 -0
  126. smallworld/state/memory/elf/rela/aarch64.py +27 -0
  127. smallworld/state/memory/elf/rela/amd64.py +32 -0
  128. smallworld/state/memory/elf/rela/arm.py +51 -0
  129. smallworld/state/memory/elf/rela/i386.py +32 -0
  130. smallworld/state/memory/elf/rela/mips.py +45 -0
  131. smallworld/state/memory/elf/rela/ppc.py +45 -0
  132. smallworld/state/memory/elf/rela/rela.py +63 -0
  133. smallworld/state/memory/elf/rela/riscv64.py +27 -0
  134. smallworld/state/memory/elf/rela/xtensa.py +15 -0
  135. smallworld/state/memory/elf/structs.py +55 -0
  136. smallworld/state/memory/heap.py +85 -0
  137. smallworld/state/memory/memory.py +181 -0
  138. smallworld/state/memory/stack/__init__.py +31 -0
  139. smallworld/state/memory/stack/aarch64.py +22 -0
  140. smallworld/state/memory/stack/amd64.py +42 -0
  141. smallworld/state/memory/stack/arm.py +66 -0
  142. smallworld/state/memory/stack/i386.py +22 -0
  143. smallworld/state/memory/stack/mips.py +34 -0
  144. smallworld/state/memory/stack/mips64.py +34 -0
  145. smallworld/state/memory/stack/ppc.py +34 -0
  146. smallworld/state/memory/stack/riscv.py +22 -0
  147. smallworld/state/memory/stack/stack.py +127 -0
  148. smallworld/state/memory/stack/xtensa.py +34 -0
  149. smallworld/state/models/__init__.py +6 -0
  150. smallworld/state/models/mmio.py +186 -0
  151. smallworld/state/models/model.py +163 -0
  152. smallworld/state/models/posix.py +455 -0
  153. smallworld/state/models/x86/__init__.py +2 -0
  154. smallworld/state/models/x86/microsoftcdecl.py +35 -0
  155. smallworld/state/models/x86/systemv.py +240 -0
  156. smallworld/state/state.py +962 -0
  157. smallworld/state/unstable/__init__.py +0 -0
  158. smallworld/state/unstable/elf.py +393 -0
  159. smallworld/state/x86_registers.py +30 -0
  160. smallworld/utils.py +935 -0
  161. smallworld_re-1.0.0.dist-info/LICENSE.txt +21 -0
  162. smallworld_re-1.0.0.dist-info/METADATA +189 -0
  163. smallworld_re-1.0.0.dist-info/RECORD +166 -0
  164. smallworld_re-1.0.0.dist-info/WHEEL +5 -0
  165. smallworld_re-1.0.0.dist-info/entry_points.txt +2 -0
  166. smallworld_re-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,630 @@
1
+ import typing
2
+
3
+ from ... import platforms
4
+ from .. import state
5
+ from . import cpu
6
+
7
+ # ARM32 has a number of variants with very odd overlaps. Rather than risk
8
+ # copy-paste errors as I figure out who gets which control registers, I've
9
+ # implemented each subsystem variant in its own mixin.
10
+
11
+
12
+ class ARM(cpu.CPU):
13
+ """Base class for ARM 32-bit CPU models.
14
+
15
+ All ARM CPUs share the same basic registers, but there are at least two
16
+ dimensions of difference for the available modes.
17
+ """
18
+
19
+ # Special registers:
20
+ # r13: stack pointer
21
+ # r14: link register
22
+ # r15: Program counter
23
+ _GENERAL_PURPOSE_REGS = [f"r{i}" for i in range(0, 13)]
24
+
25
+ def get_general_purpose_registers(self) -> typing.List[str]:
26
+ return self._GENERAL_PURPOSE_REGS
27
+
28
+ def __init__(self):
29
+ super().__init__()
30
+ # *** General-purpose registers ***
31
+ self.r0 = state.Register("r0", size=4)
32
+ self.add(self.r0)
33
+ self.r1 = state.Register("r1", size=4)
34
+ self.add(self.r1)
35
+ self.r2 = state.Register("r2", size=4)
36
+ self.add(self.r2)
37
+ self.r3 = state.Register("r3", size=4)
38
+ self.add(self.r3)
39
+ self.r4 = state.Register("r4", size=4)
40
+ self.add(self.r4)
41
+ self.r5 = state.Register("r5", size=4)
42
+ self.add(self.r5)
43
+ self.r6 = state.Register("r6", size=4)
44
+ self.add(self.r6)
45
+ self.r7 = state.Register("r7", size=4)
46
+ self.add(self.r7)
47
+ self.r8 = state.Register("r8", size=4)
48
+ self.add(self.r8)
49
+ # r9 doubles as the Static base pointer
50
+ self.r9 = state.Register("r9", size=4)
51
+ self.add(self.r9)
52
+ self.sb = state.RegisterAlias("sb", self.r9, size=4, offset=0)
53
+ self.add(self.sb)
54
+ # r10 doubles as the Stack Limit pointer
55
+ self.r10 = state.Register("r10", size=4)
56
+ self.add(self.r10)
57
+ self.sl = state.RegisterAlias("sl", self.r10, size=4, offset=0)
58
+ self.add(self.sl)
59
+ # r11 doubles as the Frame Pointer, if desired.
60
+ self.r11 = state.Register("r11", size=4)
61
+ self.add(self.r11)
62
+ self.fp = state.RegisterAlias("fp", self.r11, size=4, offset=0)
63
+ self.add(self.fp)
64
+ # r12 doubles as the Intra-call scratch register
65
+ self.r12 = state.Register("r12", size=4)
66
+ self.add(self.r12)
67
+ self.ip = state.RegisterAlias("ip", self.r12, size=4, offset=0)
68
+ self.add(self.ip)
69
+ self.sp = state.Register("sp", size=4)
70
+ self.add(self.sp)
71
+ self.lr = state.Register("lr", size=4)
72
+ self.add(self.lr)
73
+ self.pc = state.Register("pc", size=4)
74
+ self.add(self.pc)
75
+
76
+
77
+ class ARMCPUMixinM:
78
+ """Abstract class for M-series CPUs.
79
+
80
+ The main difference between M and R/A
81
+ is the available system status registers.
82
+ """
83
+
84
+ def __init__(self):
85
+ super().__init__()
86
+ # *** Special Registers ***
87
+ # Program Status Register
88
+ # NOTE: PSR can be accessed through several masked aliases.
89
+ # These are read-only, so I'm not including them.
90
+ # - apsr: Just the condition flags
91
+ # - ipsr: Just exception information
92
+ # - epsr: Just execution state info
93
+ # - iapsr: apsr | ipsr
94
+ # - eapsr: apsr | epsr
95
+ # - iepsr: ipsr | epsr
96
+ # - xpsr: apsr | ipsr | epsr
97
+ #
98
+ # NOTE: Unicorn doesn't have a model for PSR, only its aliases
99
+ self.psr = state.Register("psr", size=4)
100
+ self.add(self.psr)
101
+ # Exception Mask Register
102
+ self.primask = state.Register("primask", size=4)
103
+ self.add(self.primask)
104
+ # Base Priority Mask Register
105
+ self.basepri = state.Register("basepri", size=4)
106
+ self.add(self.basepri)
107
+ # Fault Mask Register
108
+ self.faultmask = state.Register("faultmask", size=4)
109
+ self.add(self.faultmask)
110
+ # Control register; includes a lot of flags.
111
+ self.control = state.Register("control", size=4)
112
+ self.add(self.control)
113
+
114
+ # *** Stack Pointer Bank ***
115
+ # sp is actually an alias to one of these two.
116
+ # Exactly which one depends on a bit in control.
117
+ # Emulators that care should be careful when loading state.
118
+
119
+ # Main Stack Pointer
120
+ self.msp = state.Register("msp", size=4)
121
+ self.add(self.msp)
122
+ # Process Stack Pointer
123
+ self.psp = state.Register("psp", size=4)
124
+ self.add(self.psp)
125
+
126
+
127
+ class ARMCPUMixinRA:
128
+ """Mixin for R- or A-series CPUs.
129
+
130
+ The main difference between M and R/A
131
+ is the available system status registers.
132
+ """
133
+
134
+ def __init__(self):
135
+ super().__init__()
136
+ # *** Special Registers ***
137
+ # Current Program Status Register
138
+ # NOTE: CPSR can be accessed through several masked aliases.
139
+ # These are read-only, so I'm not including them.
140
+ # - isetstate: Just includes instruction set control bits
141
+ # - itstate: Just includes state bits for Thumb IT instruction
142
+ self.cpsr = state.Register("cpsr", size=4)
143
+ self.add(self.cpsr)
144
+ # Saved Program Status Register
145
+ self.spsr = state.Register("spsr", size=4)
146
+ self.add(self.spsr)
147
+
148
+ # *** Register Banks ***
149
+ # sp, lr, and spsr are actually aliases to one of these.
150
+ # Which one they reference depends on execution mode.
151
+ # Emulators that care should be careful when loading state.
152
+ # NOTE: Use User-mode copies of registers unless the mode has its own.
153
+
154
+ # User-mode Stack Pointer
155
+ self.sp_usr = state.Register("sp_usr", size=4)
156
+ self.add(self.sp_usr)
157
+ # User-mode Link Register
158
+ self.lr_usr = state.Register("lr_usr", size=4)
159
+ self.add(self.lr_usr)
160
+ # User-mode r8
161
+ self.r8_usr = state.Register("r8_usr", size=4)
162
+ self.add(self.r8_usr)
163
+ # User-mode r9
164
+ self.r9_usr = state.Register("r9_usr", size=4)
165
+ self.add(self.r9_usr)
166
+ # User-mode r10
167
+ self.r10_usr = state.Register("r10_usr", size=4)
168
+ self.add(self.r10_usr)
169
+ # User-mode r11
170
+ self.r11_usr = state.Register("r11_usr", size=4)
171
+ self.add(self.r11_usr)
172
+ # User-mode r12
173
+ self.r12_usr = state.Register("r12_usr", size=4)
174
+ self.add(self.r12_usr)
175
+
176
+ # Hypervisor Stack Pointer
177
+ self.sp_hyp = state.Register("sp_hyp", size=4)
178
+ self.add(self.sp_hyp)
179
+ # Hypervisor Saved PSR
180
+ self.spsr_hyp = state.Register("spsr_hyp", size=4)
181
+ self.add(self.spsr_hyp)
182
+ # Hypervisor Exception Link Register
183
+ # NOTE: This isn't so much banked, as it only exists in hypervisor mode.
184
+ self.elr_hyp = state.Register("elr_hyp", size=4)
185
+ self.add(self.elr_hyp)
186
+
187
+ # Supervisor Stack Pointer
188
+ self.sp_svc = state.Register("sp_svc", size=4)
189
+ self.add(self.sp_svc)
190
+ # Supervisor Link Register
191
+ self.lr_svc = state.Register("lr_svc", size=4)
192
+ self.add(self.lr_svc)
193
+ # Supervisor Saved PSR
194
+ self.spsr_svc = state.Register("spsr_svc", size=4)
195
+ self.add(self.spsr_svc)
196
+
197
+ # Abort-state Stack Pointer
198
+ self.sp_abt = state.Register("sp_abt", size=4)
199
+ self.add(self.sp_abt)
200
+ # Abort-state Link Register
201
+ self.lr_abt = state.Register("lr_abt", size=4)
202
+ self.add(self.lr_abt)
203
+ # Abort-state Saved PSR
204
+ self.spsr_abt = state.Register("spsr_abt", size=4)
205
+ self.add(self.spsr_abt)
206
+
207
+ # Undefined-mode Stack Pointer
208
+ self.sp_und = state.Register("sp_und", size=4)
209
+ self.add(self.sp_und)
210
+ # Undefined-mode Link Register
211
+ self.lr_und = state.Register("lr_und", size=4)
212
+ self.add(self.lr_und)
213
+ # Undefined-mode Saved PSR
214
+ self.spsr_und = state.Register("spsr_und", size=4)
215
+ self.add(self.spsr_und)
216
+
217
+ # Monitor-mode Stack Pointer
218
+ self.sp_mon = state.Register("sp_mon", size=4)
219
+ self.add(self.sp_mon)
220
+ # Monitor-mode Link Register
221
+ self.lr_mon = state.Register("lr_mon", size=4)
222
+ self.add(self.lr_mon)
223
+ # Monitor-mode Saved PSR
224
+ self.spsr_mon = state.Register("spsr_mon", size=4)
225
+ self.add(self.spsr_mon)
226
+
227
+ # IRQ-mode Stack Pointer
228
+ self.sp_irq = state.Register("sp_irq", size=4)
229
+ self.add(self.sp_irq)
230
+ # IRQ-mode Link Register
231
+ self.lr_irq = state.Register("lr_irq", size=4)
232
+ self.add(self.lr_irq)
233
+ # IRQ-mode Saved PSR
234
+ self.spsr_irq = state.Register("spsr_irq", size=4)
235
+ self.add(self.spsr_irq)
236
+
237
+ # FIQ-mode Stack Pointer
238
+ self.sp_fiq = state.Register("sp_fiq", size=4)
239
+ self.add(self.sp_fiq)
240
+ # FIQ-mode Link Register
241
+ self.lr_fiq = state.Register("lr_fiq", size=4)
242
+ self.add(self.lr_fiq)
243
+ # FIQ-mode Saved PSR
244
+ self.spsr_fiq = state.Register("spsr_fiq", size=4)
245
+ self.add(self.spsr_fiq)
246
+ # FIQ-mode r8
247
+ self.r8_fiq = state.Register("r8_fiq", size=4)
248
+ self.add(self.r8_fiq)
249
+ # FIQ-mode r9
250
+ self.r9_fiq = state.Register("r9_fiq", size=4)
251
+ self.add(self.r9_fiq)
252
+ # FIQ-mode r10
253
+ self.r10_fiq = state.Register("r10_fiq", size=4)
254
+ self.add(self.r10_fiq)
255
+ # FIQ-mode r11
256
+ self.r11_fiq = state.Register("r11_fiq", size=4)
257
+ self.add(self.r11_fiq)
258
+ # FIQ-mode r12
259
+ self.r12_fiq = state.Register("r12_fiq", size=4)
260
+ self.add(self.r12_fiq)
261
+
262
+
263
+ class ARMCPUMixinFPEL:
264
+ """Mixin for little-endian ARM CPUs with FP extensions
265
+
266
+ This is one kind of floating-point extension
267
+ which offers 64-bit scalar operations
268
+ """
269
+
270
+ def __init__(self):
271
+ super().__init__()
272
+ # *** Floating point control registers ***
273
+ # Floating-point Status and Control Register
274
+ self.fpscr = state.Register("fpscr", size=4)
275
+ self.add(self.fpscr)
276
+ # Floating-point Exception Control Register
277
+ self.fpexc = state.Register("fpexc", size=4)
278
+ self.add(self.fpexc)
279
+ # Floating-point System ID Register
280
+ self.fpsid = state.Register("fpsid", size=4)
281
+ self.add(self.fpsid)
282
+ # Media and VFP Feature Register 0
283
+ self.mvfr0 = state.Register("mvfr0", size=4)
284
+ self.add(self.mvfr0)
285
+ # Media and VFP Feature Register 1
286
+ self.mvfr1 = state.Register("mvfr1", size=4)
287
+ self.add(self.mvfr1)
288
+
289
+ # *** Floating point registers ***
290
+ self.d0 = state.Register("d0", size=8)
291
+ self.add(self.d0)
292
+ self.s0 = state.RegisterAlias("s0", self.d0, size=4, offset=0)
293
+ self.add(self.s0)
294
+ self.s1 = state.RegisterAlias("s1", self.d0, size=4, offset=4)
295
+ self.add(self.s1)
296
+ self.d1 = state.Register("d1", size=8)
297
+ self.add(self.d1)
298
+ self.s2 = state.RegisterAlias("s2", self.d1, size=4, offset=0)
299
+ self.add(self.s2)
300
+ self.s3 = state.RegisterAlias("s3", self.d1, size=4, offset=4)
301
+ self.add(self.s3)
302
+ self.d2 = state.Register("d2", size=8)
303
+ self.add(self.d2)
304
+ self.s4 = state.RegisterAlias("s4", self.d2, size=4, offset=0)
305
+ self.add(self.s4)
306
+ self.s5 = state.RegisterAlias("s5", self.d2, size=4, offset=4)
307
+ self.add(self.s5)
308
+ self.d3 = state.Register("d3", size=8)
309
+ self.add(self.d3)
310
+ self.s6 = state.RegisterAlias("s6", self.d3, size=4, offset=0)
311
+ self.add(self.s6)
312
+ self.s7 = state.RegisterAlias("s7", self.d3, size=4, offset=4)
313
+ self.add(self.s7)
314
+ self.d4 = state.Register("d4", size=8)
315
+ self.add(self.d4)
316
+ self.s8 = state.RegisterAlias("s8", self.d4, size=4, offset=0)
317
+ self.add(self.s8)
318
+ self.s9 = state.RegisterAlias("s9", self.d4, size=4, offset=4)
319
+ self.add(self.s9)
320
+ self.d5 = state.Register("d5", size=8)
321
+ self.add(self.d5)
322
+ self.s10 = state.RegisterAlias("s10", self.d5, size=4, offset=0)
323
+ self.add(self.s10)
324
+ self.s11 = state.RegisterAlias("s11", self.d5, size=4, offset=4)
325
+ self.add(self.s11)
326
+ self.d6 = state.Register("d6", size=8)
327
+ self.add(self.d6)
328
+ self.s12 = state.RegisterAlias("s12", self.d6, size=4, offset=0)
329
+ self.add(self.s12)
330
+ self.s13 = state.RegisterAlias("s13", self.d6, size=4, offset=4)
331
+ self.add(self.s13)
332
+ self.d7 = state.Register("d7", size=8)
333
+ self.add(self.d7)
334
+ self.s14 = state.RegisterAlias("s14", self.d7, size=4, offset=0)
335
+ self.add(self.s14)
336
+ self.s15 = state.RegisterAlias("s15", self.d7, size=4, offset=4)
337
+ self.add(self.s15)
338
+ self.d8 = state.Register("d8", size=8)
339
+ self.add(self.d8)
340
+ self.s16 = state.RegisterAlias("s16", self.d8, size=4, offset=0)
341
+ self.add(self.s16)
342
+ self.s17 = state.RegisterAlias("s17", self.d8, size=4, offset=4)
343
+ self.add(self.s17)
344
+ self.d9 = state.Register("d9", size=8)
345
+ self.add(self.d9)
346
+ self.s18 = state.RegisterAlias("s18", self.d9, size=4, offset=0)
347
+ self.add(self.s18)
348
+ self.s19 = state.RegisterAlias("s19", self.d9, size=4, offset=4)
349
+ self.add(self.s19)
350
+ self.d10 = state.Register("d10", size=8)
351
+ self.add(self.d10)
352
+ self.s20 = state.RegisterAlias("s20", self.d10, size=4, offset=0)
353
+ self.add(self.s20)
354
+ self.s21 = state.RegisterAlias("s21", self.d10, size=4, offset=4)
355
+ self.add(self.s21)
356
+ self.d11 = state.Register("d11", size=8)
357
+ self.add(self.d11)
358
+ self.s22 = state.RegisterAlias("s22", self.d11, size=4, offset=0)
359
+ self.add(self.s22)
360
+ self.s23 = state.RegisterAlias("s23", self.d11, size=4, offset=4)
361
+ self.add(self.s23)
362
+ self.d12 = state.Register("d12", size=8)
363
+ self.add(self.d12)
364
+ self.s24 = state.RegisterAlias("s24", self.d12, size=4, offset=0)
365
+ self.add(self.s24)
366
+ self.s25 = state.RegisterAlias("s25", self.d12, size=4, offset=4)
367
+ self.add(self.s25)
368
+ self.d13 = state.Register("d13", size=8)
369
+ self.add(self.d13)
370
+ self.s26 = state.RegisterAlias("s26", self.d13, size=4, offset=0)
371
+ self.add(self.s26)
372
+ self.s27 = state.RegisterAlias("s27", self.d13, size=4, offset=4)
373
+ self.add(self.s27)
374
+ self.d14 = state.Register("d14", size=8)
375
+ self.add(self.d14)
376
+ self.s28 = state.RegisterAlias("s28", self.d14, size=4, offset=0)
377
+ self.add(self.s28)
378
+ self.s29 = state.RegisterAlias("s29", self.d14, size=4, offset=4)
379
+ self.add(self.s29)
380
+ self.d15 = state.Register("d15", size=8)
381
+ self.add(self.d15)
382
+ self.s30 = state.RegisterAlias("s30", self.d15, size=4, offset=0)
383
+ self.add(self.s30)
384
+ self.s31 = state.RegisterAlias("s31", self.d15, size=4, offset=4)
385
+ self.add(self.s31)
386
+
387
+
388
+ class ARMCPUMixinVFPEL:
389
+ """Mixin for little-endian ARM CPUs with VFP/NEON mixins
390
+
391
+ This is one kind of floating-point extension
392
+ which supports up to 128-bit scalar and SIMD vector operations.
393
+
394
+ VFP and NEON are always optional extensions;
395
+ The two can exist independently, and VFP can support either
396
+ 16 or 32 double registers.
397
+ This is the maximal set of registers, assuming both are supported.
398
+ """
399
+
400
+ def __init__(self):
401
+ super().__init__()
402
+ # *** Floating-point Control Registers ***
403
+ # Floating-point Status and Control Register
404
+ self.fpscr = state.Register("fpscr", size=4)
405
+ self.add(self.fpscr)
406
+ # Floating-point Exception Control Register
407
+ self.fpexc = state.Register("fpexc", size=4)
408
+ self.add(self.fpexc)
409
+ # Floating-point System ID Register
410
+ self.fpsid = state.Register("fpsid", size=4)
411
+ self.add(self.fpsid)
412
+ # Media and VFP Feature Register 0
413
+ self.mvfr0 = state.Register("mvfr0", size=4)
414
+ self.add(self.mvfr0)
415
+ # Media and VFP Feature Register 1
416
+ self.mvfr1 = state.Register("mvfr1", size=4)
417
+ self.add(self.mvfr1)
418
+ # *** Floating-point Registers ****
419
+ self.q0 = state.Register("q0", size=16)
420
+ self.add(self.q0)
421
+ self.d0 = state.RegisterAlias("d0", self.q0, size=8, offset=0)
422
+ self.add(self.d0)
423
+ self.s0 = state.RegisterAlias("s0", self.q0, size=4, offset=0)
424
+ self.add(self.s0)
425
+ self.s1 = state.RegisterAlias("s1", self.q0, size=4, offset=4)
426
+ self.add(self.s1)
427
+ self.d1 = state.RegisterAlias("d1", self.q0, size=8, offset=8)
428
+ self.add(self.d1)
429
+ self.s2 = state.RegisterAlias("s2", self.q0, size=4, offset=8)
430
+ self.add(self.s2)
431
+ self.s3 = state.RegisterAlias("s3", self.q0, size=4, offset=12)
432
+ self.add(self.s3)
433
+ self.q1 = state.Register("q1", size=16)
434
+ self.add(self.q1)
435
+ self.d2 = state.RegisterAlias("d2", self.q1, size=8, offset=0)
436
+ self.add(self.d2)
437
+ self.s4 = state.RegisterAlias("s4", self.q1, size=4, offset=0)
438
+ self.add(self.s4)
439
+ self.s5 = state.RegisterAlias("s5", self.q1, size=4, offset=4)
440
+ self.add(self.s5)
441
+ self.d3 = state.RegisterAlias("d3", self.q1, size=8, offset=8)
442
+ self.add(self.d3)
443
+ self.s6 = state.RegisterAlias("s6", self.q1, size=4, offset=8)
444
+ self.add(self.s6)
445
+ self.s7 = state.RegisterAlias("s7", self.q1, size=4, offset=12)
446
+ self.add(self.s7)
447
+ self.q2 = state.Register("q2", size=16)
448
+ self.add(self.q2)
449
+ self.d4 = state.RegisterAlias("d4", self.q2, size=8, offset=0)
450
+ self.add(self.d4)
451
+ self.s8 = state.RegisterAlias("s8", self.q2, size=4, offset=0)
452
+ self.add(self.s8)
453
+ self.s9 = state.RegisterAlias("s9", self.q2, size=4, offset=4)
454
+ self.add(self.s9)
455
+ self.d5 = state.RegisterAlias("d5", self.q2, size=8, offset=8)
456
+ self.add(self.d5)
457
+ self.s10 = state.RegisterAlias("s10", self.q2, size=4, offset=8)
458
+ self.add(self.s10)
459
+ self.s11 = state.RegisterAlias("s11", self.q2, size=4, offset=12)
460
+ self.add(self.s11)
461
+ self.q3 = state.Register("q3", size=16)
462
+ self.add(self.q3)
463
+ self.d6 = state.RegisterAlias("d6", self.q3, size=8, offset=0)
464
+ self.add(self.d6)
465
+ self.s12 = state.RegisterAlias("s12", self.q3, size=4, offset=0)
466
+ self.add(self.s12)
467
+ self.s13 = state.RegisterAlias("s13", self.q3, size=4, offset=4)
468
+ self.add(self.s13)
469
+ self.d7 = state.RegisterAlias("d7", self.q3, size=8, offset=8)
470
+ self.add(self.d7)
471
+ self.s14 = state.RegisterAlias("s14", self.q3, size=4, offset=8)
472
+ self.add(self.s14)
473
+ self.s15 = state.RegisterAlias("s15", self.q3, size=4, offset=12)
474
+ self.add(self.s15)
475
+ self.q4 = state.Register("q4", size=16)
476
+ self.add(self.q4)
477
+ self.d8 = state.RegisterAlias("d8", self.q4, size=8, offset=0)
478
+ self.add(self.d8)
479
+ self.s16 = state.RegisterAlias("s16", self.q4, size=4, offset=0)
480
+ self.add(self.s16)
481
+ self.s17 = state.RegisterAlias("s17", self.q4, size=4, offset=4)
482
+ self.add(self.s17)
483
+ self.d9 = state.RegisterAlias("d9", self.q4, size=8, offset=8)
484
+ self.add(self.d9)
485
+ self.s18 = state.RegisterAlias("s18", self.q4, size=4, offset=8)
486
+ self.add(self.s18)
487
+ self.s19 = state.RegisterAlias("s19", self.q4, size=4, offset=12)
488
+ self.add(self.s19)
489
+ self.q5 = state.Register("q5", size=16)
490
+ self.add(self.q5)
491
+ self.d10 = state.RegisterAlias("d10", self.q5, size=8, offset=0)
492
+ self.add(self.d10)
493
+ self.s20 = state.RegisterAlias("s20", self.q5, size=4, offset=0)
494
+ self.add(self.s20)
495
+ self.s21 = state.RegisterAlias("s21", self.q5, size=4, offset=4)
496
+ self.add(self.s21)
497
+ self.d11 = state.RegisterAlias("d11", self.q5, size=8, offset=8)
498
+ self.add(self.d11)
499
+ self.s22 = state.RegisterAlias("s22", self.q5, size=4, offset=8)
500
+ self.add(self.s22)
501
+ self.s23 = state.RegisterAlias("s23", self.q5, size=4, offset=12)
502
+ self.add(self.s23)
503
+ self.q6 = state.Register("q6", size=16)
504
+ self.add(self.q6)
505
+ self.d12 = state.RegisterAlias("d12", self.q6, size=8, offset=0)
506
+ self.add(self.d12)
507
+ self.s24 = state.RegisterAlias("s24", self.q6, size=4, offset=0)
508
+ self.add(self.s24)
509
+ self.s25 = state.RegisterAlias("s25", self.q6, size=4, offset=4)
510
+ self.add(self.s25)
511
+ self.d13 = state.RegisterAlias("d13", self.q6, size=8, offset=8)
512
+ self.add(self.d13)
513
+ self.s26 = state.RegisterAlias("s26", self.q6, size=4, offset=8)
514
+ self.add(self.s26)
515
+ self.s27 = state.RegisterAlias("s27", self.q6, size=4, offset=12)
516
+ self.add(self.s27)
517
+ self.q7 = state.Register("q7", size=16)
518
+ self.add(self.q7)
519
+ self.d14 = state.RegisterAlias("d14", self.q7, size=8, offset=0)
520
+ self.add(self.d14)
521
+ self.s28 = state.RegisterAlias("s28", self.q7, size=4, offset=0)
522
+ self.add(self.s28)
523
+ self.s29 = state.RegisterAlias("s29", self.q7, size=4, offset=4)
524
+ self.add(self.s29)
525
+ self.d15 = state.RegisterAlias("d15", self.q7, size=8, offset=8)
526
+ self.add(self.d15)
527
+ self.s30 = state.RegisterAlias("s30", self.q7, size=4, offset=8)
528
+ self.add(self.s30)
529
+ self.s31 = state.RegisterAlias("s31", self.q7, size=4, offset=12)
530
+ self.add(self.s31)
531
+ # NOTE: This isn't a typo; there are only 32 single-precision sX registers
532
+ # This does mean that only half the VFP register space can be used
533
+ # for single-precision arithmetic.
534
+ self.q8 = state.Register("q8", size=16)
535
+ self.add(self.q8)
536
+ self.d16 = state.RegisterAlias("d16", self.q8, size=8, offset=0)
537
+ self.add(self.d16)
538
+ self.d17 = state.RegisterAlias("d17", self.q8, size=8, offset=8)
539
+ self.add(self.d17)
540
+ self.q9 = state.Register("q9", size=16)
541
+ self.add(self.q9)
542
+ self.d18 = state.RegisterAlias("d18", self.q9, size=8, offset=0)
543
+ self.add(self.d18)
544
+ self.d19 = state.RegisterAlias("d19", self.q9, size=8, offset=8)
545
+ self.add(self.d19)
546
+ self.q10 = state.Register("q10", size=16)
547
+ self.add(self.q10)
548
+ self.d20 = state.RegisterAlias("d20", self.q10, size=8, offset=0)
549
+ self.add(self.d20)
550
+ self.d21 = state.RegisterAlias("d21", self.q10, size=8, offset=8)
551
+ self.add(self.d21)
552
+ self.q11 = state.Register("q11", size=16)
553
+ self.add(self.q11)
554
+ self.d22 = state.RegisterAlias("d22", self.q11, size=8, offset=0)
555
+ self.add(self.d22)
556
+ self.d23 = state.RegisterAlias("d23", self.q11, size=8, offset=8)
557
+ self.add(self.d23)
558
+ self.q12 = state.Register("q12", size=16)
559
+ self.add(self.q12)
560
+ self.d24 = state.RegisterAlias("d24", self.q12, size=8, offset=0)
561
+ self.add(self.d24)
562
+ self.d25 = state.RegisterAlias("d25", self.q12, size=8, offset=8)
563
+ self.add(self.d25)
564
+ self.q13 = state.Register("q13", size=16)
565
+ self.add(self.q13)
566
+ self.d26 = state.RegisterAlias("d26", self.q13, size=8, offset=0)
567
+ self.add(self.d26)
568
+ self.d27 = state.RegisterAlias("d27", self.q13, size=8, offset=8)
569
+ self.add(self.d27)
570
+ self.q14 = state.Register("q14", size=16)
571
+ self.add(self.q14)
572
+ self.d28 = state.RegisterAlias("d28", self.q14, size=8, offset=0)
573
+ self.add(self.d28)
574
+ self.d29 = state.RegisterAlias("d29", self.q14, size=8, offset=8)
575
+ self.add(self.d29)
576
+ self.q15 = state.Register("q15", size=16)
577
+ self.add(self.q15)
578
+ self.d30 = state.RegisterAlias("d30", self.q15, size=8, offset=0)
579
+ self.add(self.d30)
580
+ self.d31 = state.RegisterAlias("d31", self.q15, size=8, offset=8)
581
+ self.add(self.d31)
582
+
583
+
584
+ class ARMv5T(ARMCPUMixinM, ARM):
585
+ """CPU Model for ARMv5t little-endian."""
586
+
587
+ platform = platforms.Platform(
588
+ platforms.Architecture.ARM_V5T, platforms.Byteorder.LITTLE
589
+ )
590
+
591
+
592
+ class ARMv6M(ARMCPUMixinFPEL, ARMCPUMixinM, ARM):
593
+ """CPU Model for ARMv6-M little-endian."""
594
+
595
+ platform = platforms.Platform(
596
+ platforms.Architecture.ARM_V6M, platforms.Byteorder.LITTLE
597
+ )
598
+
599
+
600
+ class ARMv6MThumb(ARMv6M):
601
+ """CPU Model for ARMv6-M little-endian in thumb mode."""
602
+
603
+ platform = platforms.Platform(
604
+ platforms.Architecture.ARM_V6M_THUMB, platforms.Byteorder.LITTLE
605
+ )
606
+
607
+
608
+ class ARMv7M(ARMCPUMixinFPEL, ARMCPUMixinM, ARM):
609
+ """CPU Model for ARMv7-M little-endian."""
610
+
611
+ platform = platforms.Platform(
612
+ platforms.Architecture.ARM_V7M, platforms.Byteorder.LITTLE
613
+ )
614
+
615
+
616
+ class ARMv7R(ARMCPUMixinVFPEL, ARMCPUMixinRA, ARM):
617
+ """CPU Model for ARMv7-R little-endian."""
618
+
619
+ # TODO: v7r and v7a have different MMUs, which I don't implement yet.
620
+ platform = platforms.Platform(
621
+ platforms.Architecture.ARM_V7R, platforms.Byteorder.LITTLE
622
+ )
623
+
624
+
625
+ class ARMv7A(ARMCPUMixinVFPEL, ARMCPUMixinRA, ARM):
626
+ """CPU Model for ARMv7-A little-endian."""
627
+
628
+ platform = platforms.Platform(
629
+ platforms.Architecture.ARM_V7A, platforms.Byteorder.LITTLE
630
+ )
@@ -0,0 +1,71 @@
1
+ import abc
2
+ import typing
3
+
4
+ from ... import platforms, utils
5
+ from .. import state
6
+
7
+
8
+ class CPU(state.StatefulSet):
9
+ """A CPU state object."""
10
+
11
+ def __deepcopy__(self, memo):
12
+ new_cpu = (type(self))()
13
+ for x in self.__dict__:
14
+ a = self.__getattribute__(x)
15
+ if type(a) is state.Register:
16
+ new_cpu.__getattribute__(x).set(self.__getattribute__(x).get())
17
+ new_cpu.__getattribute__(x).set_label(
18
+ self.__getattribute__(x).get_label()
19
+ )
20
+ new_cpu.__getattribute__(x).set_type(
21
+ self.__getattribute__(x).get_type()
22
+ )
23
+ return new_cpu
24
+
25
+ @property
26
+ @abc.abstractmethod
27
+ def platform(self) -> platforms.Platform:
28
+ pass
29
+
30
+ @classmethod
31
+ def get_platform(cls) -> platforms.Platform:
32
+ """Get the platform object for this CPU.
33
+
34
+ Returns:
35
+ The platform object for this CPU.
36
+ """
37
+ if not isinstance(cls.platform, platforms.Platform):
38
+ raise TypeError(f"{cls.__name__}.platform is not a Platform object")
39
+ return cls.platform
40
+
41
+ @classmethod
42
+ def for_platform(cls, platform: platforms.Platform):
43
+ """Get a CPU object for a given platform specifier.
44
+
45
+ Arguments:
46
+ platform: The platform specificer for the desired CPU object.
47
+
48
+ Returns:
49
+ An instance of the desired CPU.
50
+ """
51
+
52
+ try:
53
+ return utils.find_subclass(cls, lambda x: x.get_platform() == platform)
54
+ except ValueError:
55
+ raise ValueError(f"no model for {platform}")
56
+
57
+ @abc.abstractmethod
58
+ def get_general_purpose_registers(self) -> typing.List[str]:
59
+ """Get a list of general purpose register names.
60
+
61
+ Returns:
62
+ A list of the general purpose register names for this CPU.
63
+ """
64
+
65
+ pass
66
+
67
+ def __repr__(self) -> str:
68
+ return f"{self.__class__.__name__}({self.platform})"
69
+
70
+
71
+ __all__ = ["CPU"]