1 //===-- RegisterContextDarwin_i386.cpp ------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/Utility/DataBufferHeap.h"
10 #include "lldb/Utility/DataExtractor.h"
11 #include "lldb/Utility/Endian.h"
12 #include "lldb/Utility/Log.h"
13 #include "lldb/Utility/RegisterValue.h"
14 #include "lldb/Utility/Scalar.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/Support/Compiler.h"
17
18 #include <cstddef>
19
20 #include <memory>
21
22 #include "RegisterContextDarwin_i386.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 enum {
28 gpr_eax = 0,
29 gpr_ebx,
30 gpr_ecx,
31 gpr_edx,
32 gpr_edi,
33 gpr_esi,
34 gpr_ebp,
35 gpr_esp,
36 gpr_ss,
37 gpr_eflags,
38 gpr_eip,
39 gpr_cs,
40 gpr_ds,
41 gpr_es,
42 gpr_fs,
43 gpr_gs,
44
45 fpu_fcw,
46 fpu_fsw,
47 fpu_ftw,
48 fpu_fop,
49 fpu_ip,
50 fpu_cs,
51 fpu_dp,
52 fpu_ds,
53 fpu_mxcsr,
54 fpu_mxcsrmask,
55 fpu_stmm0,
56 fpu_stmm1,
57 fpu_stmm2,
58 fpu_stmm3,
59 fpu_stmm4,
60 fpu_stmm5,
61 fpu_stmm6,
62 fpu_stmm7,
63 fpu_xmm0,
64 fpu_xmm1,
65 fpu_xmm2,
66 fpu_xmm3,
67 fpu_xmm4,
68 fpu_xmm5,
69 fpu_xmm6,
70 fpu_xmm7,
71
72 exc_trapno,
73 exc_err,
74 exc_faultvaddr,
75
76 k_num_registers,
77
78 // Aliases
79 fpu_fctrl = fpu_fcw,
80 fpu_fstat = fpu_fsw,
81 fpu_ftag = fpu_ftw,
82 fpu_fiseg = fpu_cs,
83 fpu_fioff = fpu_ip,
84 fpu_foseg = fpu_ds,
85 fpu_fooff = fpu_dp
86 };
87
88 enum {
89 ehframe_eax = 0,
90 ehframe_ecx,
91 ehframe_edx,
92 ehframe_ebx,
93 ehframe_ebp,
94 ehframe_esp,
95 ehframe_esi,
96 ehframe_edi,
97 ehframe_eip,
98 ehframe_eflags
99 };
100
101 enum {
102 dwarf_eax = 0,
103 dwarf_ecx,
104 dwarf_edx,
105 dwarf_ebx,
106 dwarf_esp,
107 dwarf_ebp,
108 dwarf_esi,
109 dwarf_edi,
110 dwarf_eip,
111 dwarf_eflags,
112 dwarf_stmm0 = 11,
113 dwarf_stmm1,
114 dwarf_stmm2,
115 dwarf_stmm3,
116 dwarf_stmm4,
117 dwarf_stmm5,
118 dwarf_stmm6,
119 dwarf_stmm7,
120 dwarf_xmm0 = 21,
121 dwarf_xmm1,
122 dwarf_xmm2,
123 dwarf_xmm3,
124 dwarf_xmm4,
125 dwarf_xmm5,
126 dwarf_xmm6,
127 dwarf_xmm7
128 };
129
130 #define GPR_OFFSET(reg) \
131 (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::GPR, reg))
132 #define FPU_OFFSET(reg) \
133 (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::FPU, reg) + \
134 sizeof(RegisterContextDarwin_i386::GPR))
135 #define EXC_OFFSET(reg) \
136 (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::EXC, reg) + \
137 sizeof(RegisterContextDarwin_i386::GPR) + \
138 sizeof(RegisterContextDarwin_i386::FPU))
139
140 // These macros will auto define the register name, alt name, register size,
141 // register offset, encoding, format and native register. This ensures that the
142 // register state structures are defined correctly and have the correct sizes
143 // and offsets.
144 #define DEFINE_GPR(reg, alt) \
145 #reg, alt, sizeof(((RegisterContextDarwin_i386::GPR *) NULL)->reg), \
146 GPR_OFFSET(reg), eEncodingUint, eFormatHex
147 #define DEFINE_FPU_UINT(reg) \
148 #reg, NULL, sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg), \
149 FPU_OFFSET(reg), eEncodingUint, eFormatHex
150 #define DEFINE_FPU_VECT(reg, i) \
151 #reg #i, NULL, \
152 sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg[i].bytes), \
153 FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
154 {LLDB_INVALID_REGNUM, dwarf_##reg##i, \
155 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
156 fpu_##reg##i }, \
157 nullptr, nullptr,
158
159 #define DEFINE_EXC(reg) \
160 #reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *) NULL)->reg), \
161 EXC_OFFSET(reg), eEncodingUint, eFormatHex
162 #define REG_CONTEXT_SIZE \
163 (sizeof(RegisterContextDarwin_i386::GPR) + \
164 sizeof(RegisterContextDarwin_i386::FPU) + \
165 sizeof(RegisterContextDarwin_i386::EXC))
166
167 static RegisterInfo g_register_infos[] = {
168 // Macro auto defines most stuff eh_frame DWARF
169 // GENERIC PROCESS PLUGIN LLDB
170 // =============================== =======================
171 // =================== ========================= ==================
172 // =================
173 {DEFINE_GPR(eax, nullptr),
174 {ehframe_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
175 gpr_eax},
176 nullptr,
177 nullptr,
178 },
179 {DEFINE_GPR(ebx, nullptr),
180 {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
181 gpr_ebx},
182 nullptr,
183 nullptr,
184 },
185 {DEFINE_GPR(ecx, nullptr),
186 {ehframe_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
187 gpr_ecx},
188 nullptr,
189 nullptr,
190 },
191 {DEFINE_GPR(edx, nullptr),
192 {ehframe_edx, dwarf_edx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
193 gpr_edx},
194 nullptr,
195 nullptr,
196 },
197 {DEFINE_GPR(edi, nullptr),
198 {ehframe_edi, dwarf_edi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
199 gpr_edi},
200 nullptr,
201 nullptr,
202 },
203 {DEFINE_GPR(esi, nullptr),
204 {ehframe_esi, dwarf_esi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
205 gpr_esi},
206 nullptr,
207 nullptr,
208 },
209 {DEFINE_GPR(ebp, "fp"),
210 {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
211 gpr_ebp},
212 nullptr,
213 nullptr,
214 },
215 {DEFINE_GPR(esp, "sp"),
216 {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
217 gpr_esp},
218 nullptr,
219 nullptr,
220 },
221 {DEFINE_GPR(ss, nullptr),
222 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
223 LLDB_INVALID_REGNUM, gpr_ss},
224 nullptr,
225 nullptr,
226 },
227 {DEFINE_GPR(eflags, "flags"),
228 {ehframe_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS,
229 LLDB_INVALID_REGNUM, gpr_eflags},
230 nullptr,
231 nullptr,
232 },
233 {DEFINE_GPR(eip, "pc"),
234 {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
235 gpr_eip},
236 nullptr,
237 nullptr,
238 },
239 {DEFINE_GPR(cs, nullptr),
240 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
241 LLDB_INVALID_REGNUM, gpr_cs},
242 nullptr,
243 nullptr,
244 },
245 {DEFINE_GPR(ds, nullptr),
246 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
247 LLDB_INVALID_REGNUM, gpr_ds},
248 nullptr,
249 nullptr,
250 },
251 {DEFINE_GPR(es, nullptr),
252 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
253 LLDB_INVALID_REGNUM, gpr_es},
254 nullptr,
255 nullptr,
256 },
257 {DEFINE_GPR(fs, nullptr),
258 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
259 LLDB_INVALID_REGNUM, gpr_fs},
260 nullptr,
261 nullptr,
262 },
263 {DEFINE_GPR(gs, nullptr),
264 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
265 LLDB_INVALID_REGNUM, gpr_gs},
266 nullptr,
267 nullptr,
268 },
269
270 {DEFINE_FPU_UINT(fcw),
271 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
272 LLDB_INVALID_REGNUM, fpu_fcw},
273 nullptr,
274 nullptr,
275 },
276 {DEFINE_FPU_UINT(fsw),
277 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
278 LLDB_INVALID_REGNUM, fpu_fsw},
279 nullptr,
280 nullptr,
281 },
282 {DEFINE_FPU_UINT(ftw),
283 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
284 LLDB_INVALID_REGNUM, fpu_ftw},
285 nullptr,
286 nullptr,
287 },
288 {DEFINE_FPU_UINT(fop),
289 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
290 LLDB_INVALID_REGNUM, fpu_fop},
291 nullptr,
292 nullptr,
293 },
294 {DEFINE_FPU_UINT(ip),
295 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
296 LLDB_INVALID_REGNUM, fpu_ip},
297 nullptr,
298 nullptr,
299 },
300 {DEFINE_FPU_UINT(cs),
301 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
302 LLDB_INVALID_REGNUM, fpu_cs},
303 nullptr,
304 nullptr,
305 },
306 {DEFINE_FPU_UINT(dp),
307 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
308 LLDB_INVALID_REGNUM, fpu_dp},
309 nullptr,
310 nullptr,
311 },
312 {DEFINE_FPU_UINT(ds),
313 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
314 LLDB_INVALID_REGNUM, fpu_ds},
315 nullptr,
316 nullptr,
317 },
318 {DEFINE_FPU_UINT(mxcsr),
319 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
320 LLDB_INVALID_REGNUM, fpu_mxcsr},
321 nullptr,
322 nullptr,
323 },
324 {DEFINE_FPU_UINT(mxcsrmask),
325 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
326 LLDB_INVALID_REGNUM, fpu_mxcsrmask},
327 nullptr,
328 nullptr,
329 },
330 {DEFINE_FPU_VECT(stmm, 0)},
331 {DEFINE_FPU_VECT(stmm, 1)},
332 {DEFINE_FPU_VECT(stmm, 2)},
333 {DEFINE_FPU_VECT(stmm, 3)},
334 {DEFINE_FPU_VECT(stmm, 4)},
335 {DEFINE_FPU_VECT(stmm, 5)},
336 {DEFINE_FPU_VECT(stmm, 6)},
337 {DEFINE_FPU_VECT(stmm, 7)},
338 {DEFINE_FPU_VECT(xmm, 0)},
339 {DEFINE_FPU_VECT(xmm, 1)},
340 {DEFINE_FPU_VECT(xmm, 2)},
341 {DEFINE_FPU_VECT(xmm, 3)},
342 {DEFINE_FPU_VECT(xmm, 4)},
343 {DEFINE_FPU_VECT(xmm, 5)},
344 {DEFINE_FPU_VECT(xmm, 6)},
345 {DEFINE_FPU_VECT(xmm, 7)},
346
347 {DEFINE_EXC(trapno),
348 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
349 LLDB_INVALID_REGNUM, exc_trapno},
350 nullptr,
351 nullptr,
352 },
353 {DEFINE_EXC(err),
354 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
355 LLDB_INVALID_REGNUM, exc_err},
356 nullptr,
357 nullptr,
358 },
359 {DEFINE_EXC(faultvaddr),
360 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
361 LLDB_INVALID_REGNUM, exc_faultvaddr},
362 nullptr,
363 nullptr,
364 }};
365
366 static size_t k_num_register_infos = std::size(g_register_infos);
367
RegisterContextDarwin_i386(Thread & thread,uint32_t concrete_frame_idx)368 RegisterContextDarwin_i386::RegisterContextDarwin_i386(
369 Thread &thread, uint32_t concrete_frame_idx)
370 : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
371 uint32_t i;
372 for (i = 0; i < kNumErrors; i++) {
373 gpr_errs[i] = -1;
374 fpu_errs[i] = -1;
375 exc_errs[i] = -1;
376 }
377 }
378
379 RegisterContextDarwin_i386::~RegisterContextDarwin_i386() = default;
380
InvalidateAllRegisters()381 void RegisterContextDarwin_i386::InvalidateAllRegisters() {
382 InvalidateAllRegisterStates();
383 }
384
GetRegisterCount()385 size_t RegisterContextDarwin_i386::GetRegisterCount() {
386 assert(k_num_register_infos == k_num_registers);
387 return k_num_registers;
388 }
389
390 const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)391 RegisterContextDarwin_i386::GetRegisterInfoAtIndex(size_t reg) {
392 assert(k_num_register_infos == k_num_registers);
393 if (reg < k_num_registers)
394 return &g_register_infos[reg];
395 return nullptr;
396 }
397
GetRegisterInfosCount()398 size_t RegisterContextDarwin_i386::GetRegisterInfosCount() {
399 return k_num_register_infos;
400 }
401
GetRegisterInfos()402 const RegisterInfo *RegisterContextDarwin_i386::GetRegisterInfos() {
403 return g_register_infos;
404 }
405
406 // General purpose registers
407 static uint32_t g_gpr_regnums[] = {
408 gpr_eax, gpr_ebx, gpr_ecx, gpr_edx, gpr_edi, gpr_esi, gpr_ebp, gpr_esp,
409 gpr_ss, gpr_eflags, gpr_eip, gpr_cs, gpr_ds, gpr_es, gpr_fs, gpr_gs};
410
411 // Floating point registers
412 static uint32_t g_fpu_regnums[] = {
413 fpu_fcw, fpu_fsw, fpu_ftw, fpu_fop, fpu_ip, fpu_cs,
414 fpu_dp, fpu_ds, fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1,
415 fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5, fpu_stmm6, fpu_stmm7,
416 fpu_xmm0, fpu_xmm1, fpu_xmm2, fpu_xmm3, fpu_xmm4, fpu_xmm5,
417 fpu_xmm6, fpu_xmm7};
418
419 // Exception registers
420
421 static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};
422
423 // Number of registers in each register set
424 const size_t k_num_gpr_registers = std::size(g_gpr_regnums);
425 const size_t k_num_fpu_registers = std::size(g_fpu_regnums);
426 const size_t k_num_exc_registers = std::size(g_exc_regnums);
427
428 // Register set definitions. The first definitions at register set index of
429 // zero is for all registers, followed by other registers sets. The register
430 // information for the all register set need not be filled in.
431 static const RegisterSet g_reg_sets[] = {
432 {
433 "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
434 },
435 {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
436 {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
437
438 const size_t k_num_regsets = std::size(g_reg_sets);
439
GetRegisterSetCount()440 size_t RegisterContextDarwin_i386::GetRegisterSetCount() {
441 return k_num_regsets;
442 }
443
GetRegisterSet(size_t reg_set)444 const RegisterSet *RegisterContextDarwin_i386::GetRegisterSet(size_t reg_set) {
445 if (reg_set < k_num_regsets)
446 return &g_reg_sets[reg_set];
447 return nullptr;
448 }
449
450 // Register information definitions for 32 bit i386.
GetSetForNativeRegNum(int reg_num)451 int RegisterContextDarwin_i386::GetSetForNativeRegNum(int reg_num) {
452 if (reg_num < fpu_fcw)
453 return GPRRegSet;
454 else if (reg_num < exc_trapno)
455 return FPURegSet;
456 else if (reg_num < k_num_registers)
457 return EXCRegSet;
458 return -1;
459 }
460
LogGPR(Log * log,const char * title)461 void RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) {
462 if (log) {
463 if (title)
464 LLDB_LOGF(log, "%s", title);
465 for (uint32_t i = 0; i < k_num_gpr_registers; i++) {
466 uint32_t reg = gpr_eax + i;
467 LLDB_LOGF(log, "%12s = 0x%8.8x", g_register_infos[reg].name,
468 (&gpr.eax)[reg]);
469 }
470 }
471 }
472
ReadGPR(bool force)473 int RegisterContextDarwin_i386::ReadGPR(bool force) {
474 int set = GPRRegSet;
475 if (force || !RegisterSetIsCached(set)) {
476 SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
477 }
478 return GetError(set, Read);
479 }
480
ReadFPU(bool force)481 int RegisterContextDarwin_i386::ReadFPU(bool force) {
482 int set = FPURegSet;
483 if (force || !RegisterSetIsCached(set)) {
484 SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
485 }
486 return GetError(set, Read);
487 }
488
ReadEXC(bool force)489 int RegisterContextDarwin_i386::ReadEXC(bool force) {
490 int set = EXCRegSet;
491 if (force || !RegisterSetIsCached(set)) {
492 SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
493 }
494 return GetError(set, Read);
495 }
496
WriteGPR()497 int RegisterContextDarwin_i386::WriteGPR() {
498 int set = GPRRegSet;
499 if (!RegisterSetIsCached(set)) {
500 SetError(set, Write, -1);
501 return -1;
502 }
503 SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
504 SetError(set, Read, -1);
505 return GetError(set, Write);
506 }
507
WriteFPU()508 int RegisterContextDarwin_i386::WriteFPU() {
509 int set = FPURegSet;
510 if (!RegisterSetIsCached(set)) {
511 SetError(set, Write, -1);
512 return -1;
513 }
514 SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
515 SetError(set, Read, -1);
516 return GetError(set, Write);
517 }
518
WriteEXC()519 int RegisterContextDarwin_i386::WriteEXC() {
520 int set = EXCRegSet;
521 if (!RegisterSetIsCached(set)) {
522 SetError(set, Write, -1);
523 return -1;
524 }
525 SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
526 SetError(set, Read, -1);
527 return GetError(set, Write);
528 }
529
ReadRegisterSet(uint32_t set,bool force)530 int RegisterContextDarwin_i386::ReadRegisterSet(uint32_t set, bool force) {
531 switch (set) {
532 case GPRRegSet:
533 return ReadGPR(force);
534 case FPURegSet:
535 return ReadFPU(force);
536 case EXCRegSet:
537 return ReadEXC(force);
538 default:
539 break;
540 }
541 return -1;
542 }
543
WriteRegisterSet(uint32_t set)544 int RegisterContextDarwin_i386::WriteRegisterSet(uint32_t set) {
545 // Make sure we have a valid context to set.
546 if (RegisterSetIsCached(set)) {
547 switch (set) {
548 case GPRRegSet:
549 return WriteGPR();
550 case FPURegSet:
551 return WriteFPU();
552 case EXCRegSet:
553 return WriteEXC();
554 default:
555 break;
556 }
557 }
558 return -1;
559 }
560
ReadRegister(const RegisterInfo * reg_info,RegisterValue & value)561 bool RegisterContextDarwin_i386::ReadRegister(const RegisterInfo *reg_info,
562 RegisterValue &value) {
563 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
564 int set = RegisterContextDarwin_i386::GetSetForNativeRegNum(reg);
565
566 if (set == -1)
567 return false;
568
569 if (ReadRegisterSet(set, false) != 0)
570 return false;
571
572 switch (reg) {
573 case gpr_eax:
574 case gpr_ebx:
575 case gpr_ecx:
576 case gpr_edx:
577 case gpr_edi:
578 case gpr_esi:
579 case gpr_ebp:
580 case gpr_esp:
581 case gpr_ss:
582 case gpr_eflags:
583 case gpr_eip:
584 case gpr_cs:
585 case gpr_ds:
586 case gpr_es:
587 case gpr_fs:
588 case gpr_gs:
589 value = (&gpr.eax)[reg - gpr_eax];
590 break;
591
592 case fpu_fcw:
593 value = fpu.fcw;
594 break;
595
596 case fpu_fsw:
597 value = fpu.fsw;
598 break;
599
600 case fpu_ftw:
601 value = fpu.ftw;
602 break;
603
604 case fpu_fop:
605 value = fpu.fop;
606 break;
607
608 case fpu_ip:
609 value = fpu.ip;
610 break;
611
612 case fpu_cs:
613 value = fpu.cs;
614 break;
615
616 case fpu_dp:
617 value = fpu.dp;
618 break;
619
620 case fpu_ds:
621 value = fpu.ds;
622 break;
623
624 case fpu_mxcsr:
625 value = fpu.mxcsr;
626 break;
627
628 case fpu_mxcsrmask:
629 value = fpu.mxcsrmask;
630 break;
631
632 case fpu_stmm0:
633 case fpu_stmm1:
634 case fpu_stmm2:
635 case fpu_stmm3:
636 case fpu_stmm4:
637 case fpu_stmm5:
638 case fpu_stmm6:
639 case fpu_stmm7:
640 // These values don't fit into scalar types,
641 // RegisterContext::ReadRegisterBytes() must be used for these registers
642 //::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes,
643 //10);
644 return false;
645
646 case fpu_xmm0:
647 case fpu_xmm1:
648 case fpu_xmm2:
649 case fpu_xmm3:
650 case fpu_xmm4:
651 case fpu_xmm5:
652 case fpu_xmm6:
653 case fpu_xmm7:
654 // These values don't fit into scalar types,
655 // RegisterContext::ReadRegisterBytes() must be used for these registers
656 //::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes,
657 //16);
658 return false;
659
660 case exc_trapno:
661 value = exc.trapno;
662 break;
663
664 case exc_err:
665 value = exc.err;
666 break;
667
668 case exc_faultvaddr:
669 value = exc.faultvaddr;
670 break;
671
672 default:
673 return false;
674 }
675 return true;
676 }
677
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & value)678 bool RegisterContextDarwin_i386::WriteRegister(const RegisterInfo *reg_info,
679 const RegisterValue &value) {
680 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
681 int set = GetSetForNativeRegNum(reg);
682
683 if (set == -1)
684 return false;
685
686 if (ReadRegisterSet(set, false) != 0)
687 return false;
688
689 switch (reg) {
690 case gpr_eax:
691 case gpr_ebx:
692 case gpr_ecx:
693 case gpr_edx:
694 case gpr_edi:
695 case gpr_esi:
696 case gpr_ebp:
697 case gpr_esp:
698 case gpr_ss:
699 case gpr_eflags:
700 case gpr_eip:
701 case gpr_cs:
702 case gpr_ds:
703 case gpr_es:
704 case gpr_fs:
705 case gpr_gs:
706 (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32();
707 break;
708
709 case fpu_fcw:
710 fpu.fcw = value.GetAsUInt16();
711 break;
712
713 case fpu_fsw:
714 fpu.fsw = value.GetAsUInt16();
715 break;
716
717 case fpu_ftw:
718 fpu.ftw = value.GetAsUInt8();
719 break;
720
721 case fpu_fop:
722 fpu.fop = value.GetAsUInt16();
723 break;
724
725 case fpu_ip:
726 fpu.ip = value.GetAsUInt32();
727 break;
728
729 case fpu_cs:
730 fpu.cs = value.GetAsUInt16();
731 break;
732
733 case fpu_dp:
734 fpu.dp = value.GetAsUInt32();
735 break;
736
737 case fpu_ds:
738 fpu.ds = value.GetAsUInt16();
739 break;
740
741 case fpu_mxcsr:
742 fpu.mxcsr = value.GetAsUInt32();
743 break;
744
745 case fpu_mxcsrmask:
746 fpu.mxcsrmask = value.GetAsUInt32();
747 break;
748
749 case fpu_stmm0:
750 case fpu_stmm1:
751 case fpu_stmm2:
752 case fpu_stmm3:
753 case fpu_stmm4:
754 case fpu_stmm5:
755 case fpu_stmm6:
756 case fpu_stmm7:
757 // These values don't fit into scalar types,
758 // RegisterContext::ReadRegisterBytes() must be used for these registers
759 ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),
760 value.GetByteSize());
761 return false;
762
763 case fpu_xmm0:
764 case fpu_xmm1:
765 case fpu_xmm2:
766 case fpu_xmm3:
767 case fpu_xmm4:
768 case fpu_xmm5:
769 case fpu_xmm6:
770 case fpu_xmm7:
771 // These values don't fit into scalar types,
772 // RegisterContext::ReadRegisterBytes() must be used for these registers
773 ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),
774 value.GetByteSize());
775 return false;
776
777 case exc_trapno:
778 exc.trapno = value.GetAsUInt32();
779 break;
780
781 case exc_err:
782 exc.err = value.GetAsUInt32();
783 break;
784
785 case exc_faultvaddr:
786 exc.faultvaddr = value.GetAsUInt32();
787 break;
788
789 default:
790 return false;
791 }
792 return WriteRegisterSet(set) == 0;
793 }
794
ReadAllRegisterValues(lldb::WritableDataBufferSP & data_sp)795 bool RegisterContextDarwin_i386::ReadAllRegisterValues(
796 lldb::WritableDataBufferSP &data_sp) {
797 data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);
798 if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) {
799 uint8_t *dst = data_sp->GetBytes();
800 ::memcpy(dst, &gpr, sizeof(gpr));
801 dst += sizeof(gpr);
802
803 ::memcpy(dst, &fpu, sizeof(fpu));
804 dst += sizeof(gpr);
805
806 ::memcpy(dst, &exc, sizeof(exc));
807 return true;
808 }
809 return false;
810 }
811
WriteAllRegisterValues(const lldb::DataBufferSP & data_sp)812 bool RegisterContextDarwin_i386::WriteAllRegisterValues(
813 const lldb::DataBufferSP &data_sp) {
814 if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
815 const uint8_t *src = data_sp->GetBytes();
816 ::memcpy(&gpr, src, sizeof(gpr));
817 src += sizeof(gpr);
818
819 ::memcpy(&fpu, src, sizeof(fpu));
820 src += sizeof(gpr);
821
822 ::memcpy(&exc, src, sizeof(exc));
823 uint32_t success_count = 0;
824 if (WriteGPR() == 0)
825 ++success_count;
826 if (WriteFPU() == 0)
827 ++success_count;
828 if (WriteEXC() == 0)
829 ++success_count;
830 return success_count == 3;
831 }
832 return false;
833 }
834
ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,uint32_t reg)835 uint32_t RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber(
836 lldb::RegisterKind kind, uint32_t reg) {
837 if (kind == eRegisterKindGeneric) {
838 switch (reg) {
839 case LLDB_REGNUM_GENERIC_PC:
840 return gpr_eip;
841 case LLDB_REGNUM_GENERIC_SP:
842 return gpr_esp;
843 case LLDB_REGNUM_GENERIC_FP:
844 return gpr_ebp;
845 case LLDB_REGNUM_GENERIC_FLAGS:
846 return gpr_eflags;
847 case LLDB_REGNUM_GENERIC_RA:
848 default:
849 break;
850 }
851 } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {
852 switch (reg) {
853 case dwarf_eax:
854 return gpr_eax;
855 case dwarf_ecx:
856 return gpr_ecx;
857 case dwarf_edx:
858 return gpr_edx;
859 case dwarf_ebx:
860 return gpr_ebx;
861 case dwarf_esp:
862 return gpr_esp;
863 case dwarf_ebp:
864 return gpr_ebp;
865 case dwarf_esi:
866 return gpr_esi;
867 case dwarf_edi:
868 return gpr_edi;
869 case dwarf_eip:
870 return gpr_eip;
871 case dwarf_eflags:
872 return gpr_eflags;
873 case dwarf_stmm0:
874 return fpu_stmm0;
875 case dwarf_stmm1:
876 return fpu_stmm1;
877 case dwarf_stmm2:
878 return fpu_stmm2;
879 case dwarf_stmm3:
880 return fpu_stmm3;
881 case dwarf_stmm4:
882 return fpu_stmm4;
883 case dwarf_stmm5:
884 return fpu_stmm5;
885 case dwarf_stmm6:
886 return fpu_stmm6;
887 case dwarf_stmm7:
888 return fpu_stmm7;
889 case dwarf_xmm0:
890 return fpu_xmm0;
891 case dwarf_xmm1:
892 return fpu_xmm1;
893 case dwarf_xmm2:
894 return fpu_xmm2;
895 case dwarf_xmm3:
896 return fpu_xmm3;
897 case dwarf_xmm4:
898 return fpu_xmm4;
899 case dwarf_xmm5:
900 return fpu_xmm5;
901 case dwarf_xmm6:
902 return fpu_xmm6;
903 case dwarf_xmm7:
904 return fpu_xmm7;
905 default:
906 break;
907 }
908 } else if (kind == eRegisterKindLLDB) {
909 return reg;
910 }
911 return LLDB_INVALID_REGNUM;
912 }
913
HardwareSingleStep(bool enable)914 bool RegisterContextDarwin_i386::HardwareSingleStep(bool enable) {
915 if (ReadGPR(false) != 0)
916 return false;
917
918 const uint32_t trace_bit = 0x100u;
919 if (enable) {
920 // If the trace bit is already set, there is nothing to do
921 if (gpr.eflags & trace_bit)
922 return true;
923 else
924 gpr.eflags |= trace_bit;
925 } else {
926 // If the trace bit is already cleared, there is nothing to do
927 if (gpr.eflags & trace_bit)
928 gpr.eflags &= ~trace_bit;
929 else
930 return true;
931 }
932
933 return WriteGPR() == 0;
934 }
935