UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
syms_unwind_pe_x64.c
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#ifndef SYMS_UNWIND_PE_X64_C
4#define SYMS_UNWIND_PE_X64_C
5
7// NOTE(allen): PE-x64 Unwind Function
8
11 SYMS_MemoryView *memview, SYMS_RegX64 *regs){
12 SYMS_UnwindResult result = {0};
13 SYMS_U64 missed_read_addr = 0;
14
15 //- grab ip_voff (several places can use this)
17
18 //- get pdata entry from current ip
20 {
22 if (initial_pdata_off != 0){
24 }
25 }
26
27 //- no pdata; unwind by reading stack pointer
28 if (initial_pdata == 0){
29 // read ip from stack pointer
30 SYMS_U64 sp = regs->rsp.u64;
31 SYMS_U64 new_ip = 0;
32 if (!syms_memory_view_read_struct(memview, sp, &new_ip)){
33 missed_read_addr = sp;
34 goto error_out;
35 }
36
37 // advance stack pointer
38 SYMS_U64 new_sp = sp + 8;
39
40 // commit registers
41 regs->rip.u64 = new_ip;
42 regs->rsp.u64 = new_sp;
43 }
44
45 //- got pdata; perform unwinding with exception handling
46 else{
47 // try epilog unwind
50 result = syms_unwind_pe_x64__epilog(data, bin, bin_base, memview, regs);
52 }
53
54 // try xdata unwind
57
58 // get frame reg
61
62 {
63 SYMS_U64 unwind_info_off = initial_pdata->voff_unwind_info;
65
68
69 if (frame_reg_id != 0){
71 // TODO(allen): at this point if frame_reg is zero, the exe is corrupted.
72 }
74 }
75
77 for (;;){
78 //- get unwind info & codes
82
83 //- get frame base
84 SYMS_U64 frame_base = regs->rsp.u64;
85 if (frame_reg != 0){
89 frame_base = adjusted_frame_base;
90 }
91 else{
92 frame_base = 0;
93 }
94 }
95
96 //- op code interpreter
100 // extract op code parts
103
104 // determine number of op code slots
107 slot_count += 1;
108 }
109
110 // check op code slot count
111 if (slot_count == 0 || code_ptr + slot_count > code_opl){
112 result.dead = syms_true;
113 goto end_xdata_unwind;
114 }
115
116 // set next op code pointer
118
119 // interpret this op code
120 SYMS_U64 code_voff = pdata->voff_first + code_ptr->off_in_prolog;
121 if (code_voff <= ip_voff){
122 switch (op_code){
124 {
125 // read value from stack pointer
126 SYMS_U64 sp = regs->rsp.u64;
127 SYMS_U64 value = 0;
128 if (!syms_memory_view_read_struct(memview, sp, &value)){
129 missed_read_addr = sp;
130 goto error_out;
131 }
132
133 // advance stack pointer
134 SYMS_U64 new_sp = sp + 8;
135
136 // commit registers
138 reg->u64 = value;
139 regs->rsp.u64 = new_sp;
140 }break;
141
143 {
144 // read alloc size
145 SYMS_U64 size = 0;
146 if (op_info == 0){
147 size = code_ptr[1].u16*8;
148 }
149 else if (op_info == 1){
150 size = code_ptr[1].u16 + ((SYMS_U32)code_ptr[2].u16 << 16);
151 }
152 else{
153 result.dead = syms_true;
154 goto end_xdata_unwind;
155 }
156
157 // advance stack pointer
158 SYMS_U64 sp = regs->rsp.u64;
159 SYMS_U64 new_sp = sp + size;
160
161 // advance stack pointer
162 regs->rsp.u64 = new_sp;
163 }break;
164
166 {
167 // advance stack pointer
168 regs->rsp.u64 += op_info*8 + 8;
169 }break;
170
172 {
173 // put stack pointer back to the frame base
174 regs->rsp.u64 = frame_base;
175 }break;
176
178 {
179 // read value from frame base
180 SYMS_U64 off = code_ptr[1].u16*8;
181 SYMS_U64 addr = frame_base + off;
182 SYMS_U64 value = 0;
183 if (!syms_memory_view_read_struct(memview, addr, &value)){
184 missed_read_addr = addr;
185 goto error_out;
186 }
187
188 // commit to register
190 reg->u64 = value;
191 }break;
192
194 {
195 // read value from frame base
196 SYMS_U64 off = code_ptr[1].u16 + ((SYMS_U32)code_ptr[2].u16 << 16);
197 SYMS_U64 addr = frame_base + off;
198 SYMS_U64 value = 0;
199 if (!syms_memory_view_read_struct(memview, addr, &value)){
200 missed_read_addr = addr;
201 goto error_out;
202 }
203
204 // commit to register
206 reg->u64 = value;
207 }break;
208
210 {
211 // NOTE(rjf): this was found by stepping through kernel code after an exception was
212 // thrown, encountered in the exception_stepping_tests (after the throw) in mule_main
213 // SYMS_ASSERT(!"Hit me!");
214 result.dead = syms_true;
215 // TODO(allen): ???
216 }break;
217
219 {
220 SYMS_ASSERT(!"Hit me!");
221 // TODO(allen): ???
222 }break;
223
225 {
226 // read new register values
227 SYMS_U8 buf[16];
228 SYMS_U64 off = code_ptr[1].u16*16;
229 SYMS_U64 addr = frame_base + off;
230 if (!syms_memory_view_read(memview, addr, 16, buf)){
231 missed_read_addr = addr;
232 goto error_out;
233 }
234
235 // commit to register
236 void *xmm_reg = (&regs->ymm0) + op_info;
237 syms_memmove(xmm_reg, buf, sizeof(buf));
238 }break;
239
241 {
242 // read new register values
243 SYMS_U8 buf[16];
244 SYMS_U64 off = code_ptr[1].u16 + ((SYMS_U32)code_ptr[2].u16 << 16);
245 SYMS_U64 addr = frame_base + off;
246 if (!syms_memory_view_read(memview, addr, 16, buf)){
247 missed_read_addr = addr;
248 goto error_out;
249 }
250
251 // commit to register
252 void *xmm_reg = (&regs->ymm0) + op_info;
253 syms_memmove(xmm_reg, buf, sizeof(buf));
254 }break;
255
257 {
258 // NOTE(rjf): this was found by stepping through kernel code after an exception was
259 // thrown, encountered in the exception_stepping_tests (after the throw) in mule_main
260 // SYMS_ASSERT(!"Hit me!");
261
262 if (op_info > 1){
263 result.dead = syms_true;
264 goto end_xdata_unwind;
265 }
266
267 // read values
268 SYMS_U64 sp_og = regs->rsp.u64;
270 if (op_info == 1){
271 sp_adj += 8;
272 }
273
274 SYMS_U64 ip_value = 0;
276 missed_read_addr = sp_adj;
277 goto error_out;
278 }
279
281 SYMS_U16 ss_value = 0;
283 missed_read_addr = sp_after_ip;
284 goto error_out;
285 }
286
290 missed_read_addr = sp_after_ss;
291 goto error_out;
292 }
293
295 SYMS_U64 sp_value = 0;
297 missed_read_addr = sp_after_rflags;
298 goto error_out;
299 }
300
301 // commit registers
302 regs->rip.u64 = ip_value;
303 regs->ss.u16 = ss_value;
304 regs->rflags.u64 = rflags_value;
305 regs->rsp.u64 = sp_value;
306
307 // mark machine frame
309 }break;
310 }
311 }
312 }
313
314 //- iterate pdata chain
316 if (!(flags & SYMS_UnwindPeInfoFlag_CHAINED)){
317 break;
318 }
319
323
325 }
326
327 if (!did_machframe){
328 SYMS_U64 sp = regs->rsp.u64;
329 SYMS_U64 new_ip = 0;
330 if (!syms_memory_view_read_struct(memview, sp, &new_ip)){
331 missed_read_addr = sp;
332 goto error_out;
333 }
334
335 // advance stack pointer
336 SYMS_U64 new_sp = sp + 8;
337
338 // commit registers
339 regs->rip.u64 = new_ip;
340 regs->rsp.u64 = new_sp;
341 }
342
344 }
345 }
346
347 error_out:;
348
349 if (missed_read_addr != 0){
350 SYMS_Log("Memory read miss: 0x%llx\n", missed_read_addr);
351 syms_unwind_result_missed_read(&result, missed_read_addr);
352 }
353
354 if (!result.dead){
355 result.stack_pointer = regs->rsp.u64;
356 }
357
358 return(result);
359}
360
363 SYMS_MemoryView *memview, SYMS_RegX64 *regs){
365
366 SYMS_UnwindResult result = {0};
367 SYMS_U64 missed_read_addr = 0;
368
369 //- setup parsing context
370 SYMS_U64 ip_voff = regs->rip.u64 - bin_base;
373 void* inst_base = syms_pe_ptr_from_sec_number(bin_data, bin, sec_number);
375
376 //- setup parsing variables
378 SYMS_U64 off = ip_voff - sec->virt_off;
379
380 //- parsing loop
381 for (;keep_parsing;){
383
384 SYMS_U8 inst_byte = 0;
386 off += 1;
387
388 SYMS_U8 rex = 0;
389 if ((inst_byte & 0xF0) == 0x40){
390 rex = inst_byte & 0x0F; // rex prefix
392 off += 1;
393 }
394
395 switch (inst_byte){
396 // pop
397 case 0x58:
398 case 0x59:
399 case 0x5A:
400 case 0x5B:
401 case 0x5C:
402 case 0x5D:
403 case 0x5E:
404 case 0x5F:
405 {
406 SYMS_U64 sp = regs->rsp.u64;
407 SYMS_U64 value = 0;
408 if (!syms_memory_view_read_struct(memview, sp, &value)){
409 missed_read_addr = sp;
410 goto error_out;
411 }
412
413 // modify register
414 SYMS_UnwindPeX64GprReg gpr_reg = (inst_byte - 0x58) + (rex & 1)*8;
416
417 // not a final instruction
419
420 // commit registers
421 reg->u64 = value;
422 regs->rsp.u64 = sp + 8;
423 }break;
424
425 // add $nnnn,%rsp
426 case 0x81:
427 {
428 // skip one byte (we already know what it is in this scenario)
429 off += 1;
430
431 // read the 4-byte immediate
432 SYMS_S32 imm = 0;
434 off += 4;
435
436 // not a final instruction
438
439 // update stack pointer
440 regs->rsp.u64 = (SYMS_U64)(regs->rsp.u64 + imm);
441 }break;
442
443 // add $n,%rsp
444 case 0x83:
445 {
446 // skip one byte (we already know what it is in this scenario)
447 off += 1;
448
449 // read the 1-byte immediate
450 SYMS_S8 imm = 0;
452 off += 1;
453
454 // update stack pointer
455 regs->rsp.u64 = (SYMS_U64)(regs->rsp.u64 + imm);
457 }break;
458
459 // lea imm8/imm32,$rsp
460 case 0x8D:
461 {
462 // read source register
463 SYMS_U8 modrm = 0;
465 SYMS_UnwindPeX64GprReg gpr_reg = (modrm & 7) + (rex & 1)*8;
467 SYMS_U64 reg_value = reg->u64;
468
469 // advance to the immediate
470 off += 1;
471
472 SYMS_S32 imm = 0;
473 // read 1-byte immediate
474 if ((modrm >> 6) == 1){
475 SYMS_S8 imm8 = 0;
477 imm = imm8;
478 off += 1;
479 }
480
481 // read 4-byte immediate
482 else{
484 off += 4;
485 }
486
487 regs->rsp.u64 = (SYMS_U64)(reg_value + imm);
489 }break;
490
491 // ret $nn
492 case 0xC2:
493 {
494 // read new ip
495 SYMS_U64 sp = regs->rsp.u64;
496 SYMS_U64 new_ip = 0;
497 if (!syms_memory_view_read_struct(memview, sp, &new_ip)){
498 missed_read_addr = sp;
499 goto error_out;
500 }
501
502 // read 2-byte immediate & advance stack pointer
503 SYMS_U16 imm = 0;
505 SYMS_U64 new_sp = sp + 8 + imm;
506
507 // commit registers
508 regs->rip.u64 = new_ip;
509 regs->rsp.u64 = new_sp;
510 }break;
511
512 // ret / rep; ret
513 case 0xF3:
514 {
515 SYMS_ASSERT(!"Hit me!");
516 }
517 case 0xC3:
518 {
519 // read new ip
520 SYMS_U64 sp = regs->rsp.u64;
521 SYMS_U64 new_ip = 0;
522 if (!syms_memory_view_read_struct(memview, sp, &new_ip)){
523 missed_read_addr = sp;
524 goto error_out;
525 }
526
527 // advance stack pointer
528 SYMS_U64 new_sp = sp + 8;
529
530 // commit registers
531 regs->rip.u64 = new_ip;
532 regs->rsp.u64 = new_sp;
533 }break;
534
535 // jmp nnnn
536 case 0xE9:
537 {
538 SYMS_ASSERT(!"Hit Me");
539 // TODO(allen): general idea: read the immediate, move the ip, leave the sp, done
540 // we don't have any cases to exercise this right now. no guess implementation!
541 }break;
542
543 // jmp n
544 case 0xEB:
545 {
546 SYMS_ASSERT(!"Hit Me");
547 // TODO(allen): general idea: read the immediate, move the ip, leave the sp, done
548 // we don't have any cases to exercise this right now. no guess implementation!
549 }break;
550 }
551 }
552
553 error_out:;
554
555 if (missed_read_addr != 0){
556 SYMS_Log("Memory read miss: 0x%llx\n", missed_read_addr);
557 syms_unwind_result_missed_read(&result, missed_read_addr);
558 }
559
560 SYMS_LogClose(log);
561
562 return(result);
563}
564
565
567// NOTE(allen): PE-x64 Helper Functions
568
571 SYMS_U32 result = 0;
572 switch (op_code){
573 case SYMS_UnwindPeOpCode_PUSH_NONVOL: result = 1; break;
574 case SYMS_UnwindPeOpCode_ALLOC_LARGE: result = 2; break;
575 case SYMS_UnwindPeOpCode_ALLOC_SMALL: result = 1; break;
576 case SYMS_UnwindPeOpCode_SET_FPREG: result = 1; break;
577 case SYMS_UnwindPeOpCode_SAVE_NONVOL: result = 2; break;
578 case SYMS_UnwindPeOpCode_SAVE_NONVOL_FAR: result = 3; break;
579 case SYMS_UnwindPeOpCode_EPILOG: result = 2; break;
580 case SYMS_UnwindPeOpCode_SPARE_CODE: result = 3; break;
581 case SYMS_UnwindPeOpCode_SAVE_XMM128: result = 2; break;
582 case SYMS_UnwindPeOpCode_SAVE_XMM128_FAR: result = 3; break;
583 case SYMS_UnwindPeOpCode_PUSH_MACHFRAME: result = 1; break;
584 }
585 return(result);
586}
587
591 // NOTE(allen): There are restrictions placed on how an epilog is allowed
592 // to be formed (https://docs.microsoft.com/en-us/cpp/build/prolog-and-epilog?view=msvc-160)
593 // Here we interpret machine code directly according to the rules
594 // given there to determine if the code we're looking at looks like an epilog.
595
596 // TODO(allen): Figure out how to verify this.
597
598 //- setup parsing context
599 SYMS_U64 sec_number = syms_pe_sec_number_from_voff(bin_data, bin, voff);
601 void* inst_base = syms_pe_ptr_from_sec_number(bin_data, bin, sec_number);
603
604 //- setup parsing variables
607 SYMS_U64 off = voff - sec->virt_off;
608
609 //- check first instruction
610 {
611 SYMS_U8 inst[4];
614 }
615 else{
616 if ((inst[0] & 0xF8) == 0x48){
617 switch (inst[1]){
618 // add $nnnn,%rsp
619 case 0x81:
620 {
621 if (inst[0] == 0x48 && inst[2] == 0xC4){
622 off += 7;
623 }
624 else{
626 }
627 }break;
628
629 // add $n,%rsp
630 case 0x83:
631 {
632 if (inst[0] == 0x48 && inst[2] == 0xC4){
633 off += 4;
634 }
635 else{
637 }
638 }break;
639
640 // lea n(reg),%rsp
641 case 0x8D:
642 {
643 if ((inst[0] & 0x06) == 0 &&
644 ((inst[2] >> 3) & 0x07) == 0x04 &&
645 (inst[2] & 0x07) != 0x04){
646 SYMS_U8 imm_size = (inst[2] >> 6);
647 // 1-byte immediate
648 if (imm_size == 1){
649 off += 4;
650 }
651 // 4-byte immediate
652 else if (imm_size == 2){
653 off += 7;
654 }
655 else{
657 }
658 }
659 else{
661 }
662 }break;
663 }
664 }
665 }
666 }
667
668 //- parsing loop
669 if (keep_parsing){
670 for (;;){
671 // read inst
672 SYMS_U8 inst_byte = 0;
674 goto loop_break;
675 }
676
677 // when (... I don't know ...) rely on the next byte
678 SYMS_U64 check_off = off;
680 if ((inst_byte & 0xF0) == 0x40){
681 check_off = off + 1;
683 goto loop_break;
684 }
685 }
686
687 switch (check_inst_byte){
688 // pop
689 case 0x58:case 0x59:case 0x5A:case 0x5B:
690 case 0x5C:case 0x5D:case 0x5E:case 0x5F:
691 {
692 off = check_off + 1;
693 }break;
694
695 // ret
696 case 0xC2:case 0xC3:
697 {
699 goto loop_break;
700 }break;
701
702 // jmp nnnn
703 case 0xE9:
704 {
706 SYMS_S32 imm = 0;
708 goto loop_break;
709 }
710
711 SYMS_U64 next_off = (SYMS_U64)(imm_off + sizeof(imm) + imm);
712 if (!(final_pdata->voff_first <= next_off && next_off < final_pdata->voff_one_past_last)){
713 goto loop_break;
714 }
715
716 off = next_off;
717 // TODO(allen): why isn't this just the end of the epilog?
718 }break;
719
720 // rep; ret (for amd64 prediction bug)
721 case 0xF3:
722 {
725 is_epilog = (next_inst_byte == 0xC3);
726 goto loop_break;
727 }break;
728
729 default: goto loop_break;
730 }
731 }
732
733 loop_break:;
734 }
735
736 //- fill result
737 SYMS_B32 result = is_epilog;
738 return(result);
739}
740
743 SYMS_LOCAL SYMS_Reg64 dummy = {0};
744 SYMS_Reg64 *result = &dummy;
745 switch (reg_id){
746 case SYMS_UnwindPeX64GprReg_RAX: result = &regs->rax; break;
747 case SYMS_UnwindPeX64GprReg_RCX: result = &regs->rcx; break;
748 case SYMS_UnwindPeX64GprReg_RDX: result = &regs->rdx; break;
749 case SYMS_UnwindPeX64GprReg_RBX: result = &regs->rbx; break;
750 case SYMS_UnwindPeX64GprReg_RSP: result = &regs->rsp; break;
751 case SYMS_UnwindPeX64GprReg_RBP: result = &regs->rbp; break;
752 case SYMS_UnwindPeX64GprReg_RSI: result = &regs->rsi; break;
753 case SYMS_UnwindPeX64GprReg_RDI: result = &regs->rdi; break;
754 case SYMS_UnwindPeX64GprReg_R8 : result = &regs->r8 ; break;
755 case SYMS_UnwindPeX64GprReg_R9 : result = &regs->r9 ; break;
756 case SYMS_UnwindPeX64GprReg_R10: result = &regs->r10; break;
757 case SYMS_UnwindPeX64GprReg_R11: result = &regs->r11; break;
758 case SYMS_UnwindPeX64GprReg_R12: result = &regs->r12; break;
759 case SYMS_UnwindPeX64GprReg_R13: result = &regs->r13; break;
760 case SYMS_UnwindPeX64GprReg_R14: result = &regs->r14; break;
761 case SYMS_UnwindPeX64GprReg_R15: result = &regs->r15; break;
762 }
763 return(result);
764}
765
766#endif //SYMS_UNWIND_PE_X64_C
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
Definition syms_meta_coff.h:110
SYMS_U32 virt_off
Definition syms_meta_coff.h:113
SYMS_U32 virt_size
Definition syms_meta_coff.h:112
Definition syms_base.h:410
Definition syms_pe_parser.h:15
SYMS_U64 section_array_off
Definition syms_pe_parser.h:22
Definition syms_pe.h:62
SYMS_U32 voff_unwind_info
Definition syms_pe.h:65
Definition syms_meta_regs_x64.h:6
SYMS_Reg64 r13
Definition syms_meta_regs_x64.h:20
SYMS_Reg256 ymm0
Definition syms_meta_regs_x64.h:67
SYMS_Reg16 ss
Definition syms_meta_regs_x64.h:61
SYMS_Reg64 r8
Definition syms_meta_regs_x64.h:15
SYMS_Reg64 rsi
Definition syms_meta_regs_x64.h:13
SYMS_Reg64 rcx
Definition syms_meta_regs_x64.h:8
SYMS_Reg64 rbp
Definition syms_meta_regs_x64.h:12
SYMS_Reg64 rsp
Definition syms_meta_regs_x64.h:11
SYMS_Reg64 rip
Definition syms_meta_regs_x64.h:25
SYMS_Reg64 rdx
Definition syms_meta_regs_x64.h:9
SYMS_Reg64 rdi
Definition syms_meta_regs_x64.h:14
SYMS_Reg64 rflags
Definition syms_meta_regs_x64.h:26
SYMS_Reg64 r12
Definition syms_meta_regs_x64.h:19
SYMS_Reg64 rbx
Definition syms_meta_regs_x64.h:10
SYMS_Reg64 r9
Definition syms_meta_regs_x64.h:16
SYMS_Reg64 r15
Definition syms_meta_regs_x64.h:22
SYMS_Reg64 r11
Definition syms_meta_regs_x64.h:18
SYMS_Reg64 rax
Definition syms_meta_regs_x64.h:7
SYMS_Reg64 r14
Definition syms_meta_regs_x64.h:21
SYMS_Reg64 r10
Definition syms_meta_regs_x64.h:17
Definition syms_base.h:296
SYMS_U8 * str
Definition syms_base.h:297
Definition syms_base.h:264
Definition syms_unwind_pe_x64.h:49
Definition syms_base.h:420
SYMS_U64 stack_pointer
Definition syms_base.h:424
SYMS_B32 dead
Definition syms_base.h:421
SYMS_API SYMS_U64 syms_based_range_read(void *base, SYMS_U64Range range, SYMS_U64 offset, SYMS_U64 out_size, void *out)
Definition syms_base.c:753
SYMS_API SYMS_B32 syms_memory_view_read(SYMS_MemoryView *memview, SYMS_U64 addr, SYMS_U64 size, void *ptr)
Definition syms_base.c:849
SYMS_API void syms_unwind_result_missed_read(SYMS_UnwindResult *unwind_result, SYMS_U64 addr)
Definition syms_base.c:861
#define syms_true
Definition syms_base.h:105
#define syms_based_range_read_struct(b, r, o, p)
Definition syms_base.h:593
#define syms_memory_view_read_struct(s, a, p)
Definition syms_base.h:602
#define SYMS_AlignPow2(a, b)
Definition syms_base.h:187
#define SYMS_LOCAL
Definition syms_base.h:43
#define syms_false
Definition syms_base.h:104
#define SYMS_API
Definition syms_base.h:29
#define SYMS_ASSERT(x)
Definition syms_base.h:125
SYMS_S32 SYMS_B32
Definition syms_base.h:99
int32_t SYMS_S32
Definition syms_crt_overrides.h:34
uint32_t SYMS_U32
Definition syms_crt_overrides.h:38
uint64_t SYMS_U64
Definition syms_crt_overrides.h:39
#define syms_memmove
Definition syms_crt_overrides.h:65
#define SYMS_U64
Definition syms_crt_overrides.h:54
#define SYMS_U32
Definition syms_crt_overrides.h:53
uint16_t SYMS_U16
Definition syms_crt_overrides.h:37
uint8_t SYMS_U8
Definition syms_crt_overrides.h:36
int8_t SYMS_S8
Definition syms_crt_overrides.h:32
#define SYMS_LogClose(block)
Definition syms_dev.h:142
#define SYMS_LogOpen(ftr, uid, block)
Definition syms_dev.h:141
@ SYMS_LogFeature_PEEpilog
Definition syms_dev.h:27
#define SYMS_Log(fmt,...)
Definition syms_dev.h:143
SYMS_API void * syms_pe_ptr_from_voff(SYMS_String8 data, SYMS_PeBinAccel *bin, SYMS_U64 voff)
Definition syms_pe_parser.c:533
SYMS_API SYMS_U64 syms_pe_binary_search_intel_pdata(SYMS_String8 data, SYMS_PeBinAccel *bin, SYMS_U64 voff)
Definition syms_pe_parser.c:440
SYMS_API SYMS_U64 syms_pe_sec_number_from_voff(SYMS_String8 data, SYMS_PeBinAccel *bin, SYMS_U64 voff)
Definition syms_pe_parser.c:495
SYMS_API void * syms_pe_ptr_from_sec_number(SYMS_String8 data, SYMS_PeBinAccel *bin, SYMS_U64 n)
Definition syms_pe_parser.c:510
SYMS_API SYMS_CoffSectionHeader * syms_pecoff_sec_hdr_from_n(SYMS_String8 data, SYMS_U64 sec_hrds_off, SYMS_U64 n)
Definition syms_pecoff_helpers.c:7
SYMS_API SYMS_Reg64 * syms_unwind_pe_x64__gpr_reg(SYMS_RegX64 *regs, SYMS_UnwindPeX64GprReg reg_id)
Definition syms_unwind_pe_x64.c:742
SYMS_API SYMS_B32 syms_unwind_pe_x64__voff_is_in_epilog(SYMS_String8 bin_data, SYMS_PeBinAccel *bin, SYMS_U64 voff, SYMS_PeIntelPdata *final_pdata)
Definition syms_unwind_pe_x64.c:589
SYMS_API SYMS_U32 syms_unwind_pe_x64__slot_count_from_op_code(SYMS_UnwindPeOpCode op_code)
Definition syms_unwind_pe_x64.c:570
SYMS_API SYMS_UnwindResult syms_unwind_pe_x64(SYMS_String8 data, SYMS_PeBinAccel *bin, SYMS_U64 bin_base, SYMS_MemoryView *memview, SYMS_RegX64 *regs)
Definition syms_unwind_pe_x64.c:10
SYMS_API SYMS_UnwindResult syms_unwind_pe_x64__epilog(SYMS_String8 bin_data, SYMS_PeBinAccel *bin, SYMS_U64 bin_base, SYMS_MemoryView *memview, SYMS_RegX64 *regs)
Definition syms_unwind_pe_x64.c:362
@ SYMS_UnwindPeInfoFlag_CHAINED
Definition syms_unwind_pe_x64.h:41
#define SYMS_UnwindPeInfo_FlagsFromHeader(x)
Definition syms_unwind_pe_x64.h:45
#define SYMS_UnwindPeInfo_RegFromFrame(x)
Definition syms_unwind_pe_x64.h:46
#define SYMS_UnwindPeCode_InfoFromFlags(x)
Definition syms_unwind_pe_x64.h:26
#define SYMS_UnwindPeInfo_OffFromFrame(x)
Definition syms_unwind_pe_x64.h:47
#define SYMS_UnwindPeCode_CodeFromFlags(x)
Definition syms_unwind_pe_x64.h:25
SYMS_U32 SYMS_UnwindPeOpCode
Definition syms_unwind_pe_x64.h:10
SYMS_U8 SYMS_UnwindPeX64GprReg
Definition syms_unwind_pe_x64.h:59
@ SYMS_UnwindPeX64GprReg_RSI
Definition syms_unwind_pe_x64.h:67
@ SYMS_UnwindPeX64GprReg_R14
Definition syms_unwind_pe_x64.h:75
@ SYMS_UnwindPeX64GprReg_R12
Definition syms_unwind_pe_x64.h:73
@ SYMS_UnwindPeX64GprReg_RBP
Definition syms_unwind_pe_x64.h:66
@ SYMS_UnwindPeX64GprReg_R8
Definition syms_unwind_pe_x64.h:69
@ SYMS_UnwindPeX64GprReg_RCX
Definition syms_unwind_pe_x64.h:62
@ SYMS_UnwindPeX64GprReg_R9
Definition syms_unwind_pe_x64.h:70
@ SYMS_UnwindPeX64GprReg_R13
Definition syms_unwind_pe_x64.h:74
@ SYMS_UnwindPeX64GprReg_RDX
Definition syms_unwind_pe_x64.h:63
@ SYMS_UnwindPeX64GprReg_RAX
Definition syms_unwind_pe_x64.h:61
@ SYMS_UnwindPeX64GprReg_RBX
Definition syms_unwind_pe_x64.h:64
@ SYMS_UnwindPeX64GprReg_RDI
Definition syms_unwind_pe_x64.h:68
@ SYMS_UnwindPeX64GprReg_RSP
Definition syms_unwind_pe_x64.h:65
@ SYMS_UnwindPeX64GprReg_R10
Definition syms_unwind_pe_x64.h:71
@ SYMS_UnwindPeX64GprReg_R15
Definition syms_unwind_pe_x64.h:76
@ SYMS_UnwindPeX64GprReg_R11
Definition syms_unwind_pe_x64.h:72
@ SYMS_UnwindPeOpCode_SAVE_XMM128_FAR
Definition syms_unwind_pe_x64.h:21
@ SYMS_UnwindPeOpCode_EPILOG
Definition syms_unwind_pe_x64.h:18
@ SYMS_UnwindPeOpCode_ALLOC_LARGE
Definition syms_unwind_pe_x64.h:13
@ SYMS_UnwindPeOpCode_SET_FPREG
Definition syms_unwind_pe_x64.h:15
@ SYMS_UnwindPeOpCode_PUSH_MACHFRAME
Definition syms_unwind_pe_x64.h:22
@ SYMS_UnwindPeOpCode_SAVE_XMM128
Definition syms_unwind_pe_x64.h:20
@ SYMS_UnwindPeOpCode_PUSH_NONVOL
Definition syms_unwind_pe_x64.h:12
@ SYMS_UnwindPeOpCode_ALLOC_SMALL
Definition syms_unwind_pe_x64.h:14
@ SYMS_UnwindPeOpCode_SAVE_NONVOL_FAR
Definition syms_unwind_pe_x64.h:17
@ SYMS_UnwindPeOpCode_SPARE_CODE
Definition syms_unwind_pe_x64.h:19
@ SYMS_UnwindPeOpCode_SAVE_NONVOL
Definition syms_unwind_pe_x64.h:16
SYMS_U16 u16
Definition syms_regs.h:11
Definition syms_regs.h:20
SYMS_U64 u64
Definition syms_regs.h:22
Definition syms_unwind_pe_x64.h:28