UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
syms_unwind_elf_x64.c
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#ifndef SYMS_UNWIND_ELF_X64_C
4#define SYMS_UNWIND_ELF_X64_C
5
7// NOTE(allen): Generated Code
8
10
12// NOTE(allen): ELF-x64 Unwind Function
13
16 SYMS_MemoryView *memview, SYMS_U64 stack_pointer, SYMS_DwRegsX64 *regs){
19
21
22 SYMS_UnwindResult result = {0};
23
24 //- rebase
25 SYMS_U64 default_vbase = syms_elf_default_vbase_from_bin(bin);
26 SYMS_U64 rebase_voff_to_vaddr = (bin_base - default_vbase);
27
28 //- get ip register values
29 SYMS_U64 ip_value = regs->rip;
31
32 //- get sections
33 SYMS_ElfSection *sec_text = syms_elf_sec_from_bin_name__unstable(bin, syms_str8_lit(".text")); // TODO(nick): What if ELF has two sections with instructions and pointer is ecnoded relative to .text2?
36
37 //- check sections
40 SYMS_Log("Does not have needed sections\n");
41 result.dead = syms_true;
42 }
43
44 //- get frame info range
45 void *frame_base = 0;
48 frame_base = bin_data.str + sec_frame_info->file_range.min;
49 frame_range.max = sec_frame_info->file_range.max - sec_frame_info->file_range.min;
50 }
51
52 //- section vaddrs
56 text_base_vaddr = sec_text->virtual_range.min + rebase_voff_to_vaddr;
57 frame_base_voff = sec_frame_info->virtual_range.min;
58 }
60 if (sec_extra_data != 0){
62 }
63
64 //- find cfi records
67 SYMS_DwEhPtrCtx ptr_ctx = {0};
68 // TODO(allen): name?
72 ptr_ctx.func_vaddr = 0;
73 if (sec_extra_data != 0){
74 cfi_recs = syms_unwind_elf_x64__eh_frame_hdr_from_ip(bin_data.str, sec_extra_data->file_range, sec_frame_info->file_range, &ptr_ctx, ip_voff);
75 }
76 else{
78 }
79 }
80
81 //- check cfi records
82 if (!cfi_recs.valid){
83 SYMS_Log("No matching CFI record\n");
84 result.dead = syms_true;
85 }
86
87 //- cfi machine setup
88 SYMS_DwCFIMachine machine = {0};
89 if (cfi_recs.valid){
90 SYMS_DwEhPtrCtx ptr_ctx = {0};
91 // TODO(allen): name?
95 // NOTE: It's not super clear how to set up this member.
96 ptr_ctx.func_vaddr = cfi_recs.fde.ip_voff_range.min + rebase_voff_to_vaddr;
98 }
99
100 //- initial row
102 if (cfi_recs.valid){
103 SYMS_U64Range init_cfi_range = cfi_recs.cie.cfi_range;
106 init_row = row;
107 }
108 if (init_row == 0){
109 SYMS_Log("Could not decode initial row\n");
110 result.dead = syms_true;
111 }
112 }
113
114 //- main row
116 if (init_row != 0){
117 // upgrade machine with new equipment
119 syms_unwind_elf_x64__machine_equip_fde_ip(&machine, cfi_recs.fde.ip_voff_range.min);
120
121 // decode main row
122 SYMS_U64Range main_cfi_range = cfi_recs.fde.cfi_range;
125 main_row = row;
126 }
127 if (main_row == 0){
128 SYMS_Log("Could not decode main row\n");
129 result.dead = syms_true;
130 }
131 }
132
133 //- apply main row to modify the registers
134 if (main_row != 0){
135 result = syms_unwind_elf_x64__apply_rules(bin_data, main_row, text_base_vaddr, memview, stack_pointer, regs);
136 }
137
139 SYMS_LogClose(log);
140
141 return(result);
142}
143
146 SYMS_MemoryView *memview, SYMS_U64 stack_pointer, SYMS_DwRegsX64 *regs){
148
149 SYMS_UnwindResult result = {0};
150 SYMS_U64 missed_read_addr = 0;
151
152 //- setup a dwarf expression machine
155 dwexpr_config.memview = memview;
156 dwexpr_config.regs = regs;
157 dwexpr_config.text_section_base = &text_base_vaddr;
158
159 //- compute cfa
160 SYMS_U64 cfa = 0;
161 switch (row->cfa_cell.rule){
163 {
164 SYMS_Log("CFA rule: REGOFF(%llu,0x%llx)\n", row->cfa_cell.reg_idx, row->cfa_cell.offset);
165
166 // TODO(allen): have we done anything to gaurantee reg_idx here?
167 SYMS_U64 reg_idx = row->cfa_cell.reg_idx;
168
169 // is this a roll-over CFA?
171 if (reg_idx == SYMS_DwRegX64_RSP){
172 SYMS_DwCFIRegisterRule rule = row->cells[reg_idx].rule;
175 SYMS_Log("CFA rollover\n");
177 }
178 }
179
180 // compute cfa
181 if (is_roll_over_cfa){
182 cfa = stack_pointer + row->cfa_cell.offset;
183 }
184 else{
185 cfa = regs->r[reg_idx] + row->cfa_cell.offset;
186 }
187 }break;
188
190 {
191 SYMS_Log("CFA rule: EXPR\n");
192 SYMS_U64Range expr_range = row->cfa_cell.expr;
194 if (location.non_piece_loc.kind == SYMS_DwSimpleLocKind_Fail &&
195 location.non_piece_loc.fail_kind == SYMS_DwLocFailKind_MissingMemory){
196 missed_read_addr = location.non_piece_loc.fail_data;
197 goto error_out;
198 }
199 if (location.non_piece_loc.kind == SYMS_DwSimpleLocKind_Address){
200 cfa = location.non_piece_loc.addr;
201 }
202 }break;
203 }
204 SYMS_Log("CFA value: 0x%llx\n", cfa);
205
206 //- compute registers
207 {
208 SYMS_DwCFICell *cell = row->cells;
210 for (SYMS_U64 i = 0; i < SYMS_UNWIND_ELF_X64__REG_SLOT_COUNT; i += 1, cell += 1){
211 SYMS_Log("REG[%llu] RULE: ", i);
212
213 // compute value
214 SYMS_U64 v = 0;
215 switch (cell->rule){
216 default:
217 {
218 SYMS_Log("UNEXPECTED-RULE\n");
219 }break;
220
222 {
223 SYMS_Log("UNDEFINED\n");
224 }break;
225
227 {
228 SYMS_Log("SAME_VALUE\n");
229 v = regs->r[i];
230 }break;
231
233 {
234 SYMS_Log("OFFSET [cfa + %llx]\n", cell->n);
235 SYMS_U64 addr = cfa + cell->n;
236 if (!syms_memory_view_read_struct(memview, addr, &v)){
237 missed_read_addr = addr;
238 goto error_out;
239 }
240 }break;
241
243 {
244 SYMS_Log("VAL_OFFSET (cfa + %llx)\n", cell->n);
245 v = cfa + cell->n;
246 }break;
247
249 {
250 SYMS_Log("REGISTER r[%llu]\n", cell->n);
251 v = regs->r[i];
252 }break;
253
255 {
256 SYMS_Log("EXPRESSION\n");
257
259 SYMS_U64 addr = 0;
261 if (location.non_piece_loc.kind == SYMS_DwSimpleLocKind_Fail &&
262 location.non_piece_loc.fail_kind == SYMS_DwLocFailKind_MissingMemory){
263 missed_read_addr = location.non_piece_loc.fail_data;
264 goto error_out;
265 }
266 if (location.non_piece_loc.kind == SYMS_DwSimpleLocKind_Address){
267 addr = location.non_piece_loc.addr;
268 }
269 if (!syms_memory_view_read_struct(memview, addr, &v)){
270 missed_read_addr = addr;
271 goto error_out;
272 }
273 }break;
274
276 {
277 SYMS_Log("VAL_EXPRESSION\n");
278
281 if (location.non_piece_loc.kind == SYMS_DwSimpleLocKind_Fail &&
282 location.non_piece_loc.fail_kind == SYMS_DwLocFailKind_MissingMemory){
283 missed_read_addr = location.non_piece_loc.fail_data;
284 goto error_out;
285 }
286 if (location.non_piece_loc.kind == SYMS_DwSimpleLocKind_Address){
287 v = location.non_piece_loc.addr;
288 }
289 }break;
290 }
291
292 // commit value to output slot
293 new_regs.r[i] = v;
294
295 SYMS_Log("REG[%llu] VAL: 0x%llx\n", i, v);
296 }
297
298 //- commit all new regs
299 syms_memmove(regs, &new_regs, sizeof(new_regs));
300 }
301
302 //- save new stack pointer
303 result.stack_pointer = cfa;
304
305 error_out:;
306 if (missed_read_addr != 0){
307 SYMS_Log("Memory read miss: 0x%llx\n", missed_read_addr);
308 syms_unwind_result_missed_read(&result, missed_read_addr);
309 }
310
311 SYMS_LogClose(log);
312
313 return(result);
314}
315
316
318// NOTE(allen): ELF-x64 Unwind Helper Functions
319
320SYMS_API void
323
324 if (!did_init){
326
327 // control bits tables
351
355 }
356}
357
360 SYMS_DwEhPtrCtx *ptr_ctx, SYMS_DwEhPtrEnc encoding,
362
363 // aligned offset
364 SYMS_U64 pointer_off = off;
365 if (encoding == SYMS_DwEhPtrEnc_ALIGNED){
366 pointer_off = (off + 7) & ~7; // TODO(nick): align to 4 bytes when we parse x86 ELF binary
367 encoding = SYMS_DwEhPtrEnc_PTR;
368 }
369
370 // decode pointer value
374 switch (encoding & SYMS_DwEhPtrEnc_TYPE_MASK){
375 default:break;
376
377 case SYMS_DwEhPtrEnc_PTR :size_param = 8; goto ufixed;
381 ufixed:
382 {
385 }break;
386
387 // TODO(nick): SIGNED is actually just a flag that indicates this int is negavite.
388 // There shouldn't be a read when for SIGNED.
389 // For instance, (SYMS_Dw_EhPtrEnc_UDATA2 | SYMS_DwEhPtrEnc_SIGNED) == SYMS_DwEhPtrEnc_SDATA etc.
391
395 sfixed:
396 {
399 // sign extension
401 if ((raw_pointer >> sign_bit) != 0){
402 raw_pointer |= (~(1 << sign_bit)) + 1;
403 }
404 }break;
405
407 {
410 }break;
411
413 {
417 }break;
418 }
419
420 // apply relative bases
421 SYMS_U64 pointer = raw_pointer;
422 if (pointer != 0){
423 switch (encoding & SYMS_DwEhPtrEnc_MODIF_MASK){
425 {
426 pointer = ptr_ctx->raw_base_vaddr + frame_range.min + off + raw_pointer;
427 }break;
429 {
430 pointer = ptr_ctx->text_vaddr + raw_pointer;
431 }break;
433 {
434 pointer = ptr_ctx->data_vaddr + raw_pointer;
435 }break;
437 {
438 // TODO(allen): find some strong indication of how to actually fill func_vaddr
439 pointer = ptr_ctx->func_vaddr + raw_pointer;
440 }break;
441 }
442 }
443
444 // return
445 *ptr_out = pointer;
446 SYMS_U64 result = after_pointer_off - off;
447 return(result);
448}
449
450//- eh_frame parsing
451
452SYMS_API void
456
457 // get version
458 SYMS_U64 version_off = off;
459 SYMS_U8 version = 0;
460 syms_based_range_read(base, range, version_off, 1, &version);
461
462 // check version
463 if (version == 1 || version == 3){
464
465 // read augmentation
468
469 // read code align
471 SYMS_U64 code_align_factor = 0;
473 code_align_factor_off, &code_align_factor);
474
475 // read data align
477 SYMS_S64 data_align_factor = 0;
479 data_align_factor_off, &data_align_factor);
480
481 // return address register
484 SYMS_U64 ret_addr_reg = 0;
485 if (version == 1){
486 syms_based_range_read(base, range, ret_addr_reg_off, 1, &ret_addr_reg);
488 }
489 else{
491 ret_addr_reg_off, &ret_addr_reg);
493 }
494
495 // TODO(nick):
496 // Handle "eh" param, it indicates presence of EH Data field.
497 // On 32bit arch it is a 4-byte and on 64-bit 8-byte value.
498 // Reference: https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html
499 // Reference doc doesn't clarify structure for EH Data though
500
501 // check for augmentation data
504 SYMS_B8 has_augmentation_size = syms_false;
505 SYMS_U64 augmentation_size = 0;
506 if (augmentation.size > 0 && augmentation.str[0] == 'z'){
507 has_augmentation_size = syms_true;
508 SYMS_U64 aug_size_size = syms_based_range_read_uleb128(base, range, aug_size_off, &augmentation_size);
510 }
511
512 // read augmentation data
515
517 SYMS_U64 handler_ip = 0;
519
520 if (has_augmentation_size > 0){
522 for (SYMS_U8 *ptr = augmentation.str + 1, *opl = augmentation.str + augmentation.size;
523 ptr < opl;
524 ptr += 1){
525 switch (*ptr){
526 case 'L':
527 {
528 syms_based_range_read_struct(base, range, aug_data_cursor, &lsda_encoding);
529 aug_data_cursor += sizeof(lsda_encoding);
530 }break;
531
532 case 'P':
533 {
536
539 ptr_ctx, handler_encoding,
540 ptr_off, &handler_ip);
542 }break;
543
544 case 'R':
545 {
546 syms_based_range_read_struct(base, range, aug_data_cursor, &addr_encoding);
547 aug_data_cursor += sizeof(addr_encoding);
548
549 }break;
550
551 default:
552 {
553 goto dbl_break_aug;
554 }break;
555 }
556 }
559 }
560
561 // cfi range
563 SYMS_U64 cfi_size = 0;
564 if (range.max > cfi_off){
565 cfi_size = range.max - cfi_off;
566 }
567
568 // commit values to out
569 cie_out->version = version;
570 cie_out->lsda_encoding = lsda_encoding;
571 cie_out->addr_encoding = addr_encoding;
572 cie_out->has_augmentation_size = has_augmentation_size;
573 cie_out->augmentation_size = augmentation_size;
574 cie_out->augmentation = augmentation;
575 cie_out->code_align_factor = code_align_factor;
576 cie_out->data_align_factor = data_align_factor;
577 cie_out->ret_addr_reg = ret_addr_reg;
578 cie_out->handler_ip = handler_ip;
579 cie_out->cfi_range.min = cfi_off;
580 cie_out->cfi_range.max = cfi_off + cfi_size;
581 }
582}
583
584SYMS_API void
587 // pull out pointer encoding field
589
590 // ip first
592 SYMS_U64 ip_first = 0;
595
596 // ip range size
602
603 // augmentation data
606 SYMS_U64 lsda_ip = 0;
607
608 if (cie->has_augmentation_size){
609 // augmentation size
610 SYMS_U64 augmentation_size = 0;
611 SYMS_U64 aug_size_size = syms_based_range_read_uleb128(base, range, aug_data_off, &augmentation_size);
613
614 // extract lsda (only thing that can actually be in FDE's augmentation data as far as we know)
615 SYMS_DwEhPtrEnc lsda_encoding = cie->lsda_encoding;
616 if (lsda_encoding != SYMS_DwEhPtrEnc_OMIT){
618 syms_unwind_elf_x64__parse_pointer(base, range, ptr_ctx, lsda_encoding, lsda_off, &lsda_ip);
619 }
620
621 // set offset at end of augmentation data
622 after_aug_data_off = after_aug_size_off + augmentation_size;
623 }
624
625 // cfi range
627 SYMS_U64 cfi_size = 0;
628 if (range.max > cfi_off){
629 cfi_size = range.max - cfi_off;
630 }
631
632 // commit values to out
633 fde_out->ip_voff_range.min = ip_first;
634 fde_out->ip_voff_range.max = ip_first + ip_range_size;
635 fde_out->lsda_ip = lsda_ip;
636 fde_out->cfi_range.min = cfi_off;
637 fde_out->cfi_range.max = cfi_off + cfi_size;
638}
639
644
645 SYMS_DwCFIRecords result = {0};
646
650
651 SYMS_U64 cursor = 0;
652 for (;;){
653 // CIE/FDE size
654 SYMS_U64 rec_off = cursor;
656 SYMS_U64 rec_size = 0;
657
658 {
659 syms_based_range_read(base, range, rec_off, 4, &rec_size);
661 if (rec_size == SYMS_U32_MAX){
662 syms_based_range_read(base, range, rec_off + 4, 8, &rec_size);
664 }
665 }
666
667 // zero size is the end of the loop
668 if (rec_size == 0){
669 break;
670 }
671
672 // compute end offset
674
675 // sub-range the rest of the reads
677 rec_range.min = range.min + rec_off;
678 rec_range.max = range.min + rec_opl;
679
680 // discriminator
682 SYMS_U32 discrim = 0;
684
686
687 // CIE
688 if (discrim == 0){
691 if (node->cie.version != 0){
693 node->offset = range.min + rec_off;
694 }
695 }
696
697 // FDE
698 else{
699 // compute cie offset
701
702 // get cie node
705 node != 0;
706 node = node->next){
707 if (node->offset == cie_offset){
708 cie_node = node;
709 break;
710 }
711 }
712
713 // parse fde
714 SYMS_DwFDEUnpacked fde = {0};
715 if (cie_node != 0){
717 }
718
719 if (fde.ip_voff_range.min <= ip_voff && ip_voff < fde.ip_voff_range.max){
720 SYMS_Log("CIE/FDE match {CIE:0x%llx, FDE:0x%llx}\n", cie_offset, rec_range.min);
721 result.valid = syms_true;
722 result.cie = cie_node->cie;
723 result.fde = fde;
724 break;
725 }
726 }
727
728 // advance cursor
729 cursor = rec_opl;
730 }
731
733
734 SYMS_LogClose(log);
735
736 return(result);
737}
738
741{
742 // Table contains only addresses for first instruction in a function and we cannot
743 // guarantee that result is FDE that corresponds to the input location.
744 // So input location must be cheked against range from FDE header again.
745
748
750
751 SYMS_U8 version = 0;
752 read_offset += syms_based_range_read_struct(base, range, read_offset, &version);
753
754 if (version == 1){
755#if 0
756 SYMS_DwEhPtrCtx ptr_ctx; syms_memzero_struct(&ptr_ctx);
757 // Set this to base address of .eh_frame_hdr. Entries are relative
758 // to this section for some reason.
759 ptr_ctx.data_vaddr = range.min;
760 // If input location is VMA then set this to address of .text.
761 // Pointer parsing function will adjust "init_location" to correct VMA.
762 ptr_ctx.text_vaddr = 0;
763#endif
764
769
773
774 for (SYMS_U64 fde_idx = 0; fde_idx < fde_count; ++fde_idx){
775 SYMS_U64 init_location = 0, address = 0;
777 read_offset += syms_unwind_elf_x64__parse_pointer(base, range, ptr_ctx, table_enc, read_offset, &address);
778
783 closest_address = address;
784 }
785 }
786 }
787
788 // address where to find corresponding FDE, this is an absolute offset
789 // into the image file.
790 return closest_address;
791}
792
795{
796 SYMS_DwCFIRecords result; syms_memzero_struct(&result);
797
798 // find FDE offset
799 void *eh_frame_hdr = (void*)((SYMS_U8*)base+eh_frame_hdr_range.min);
801
805
806 // read FDE size
807 SYMS_U64 fde_size = 0;
809
810 // read FDE discriminator
813
814 // compute parent CIE offset
816
817 // read CIE size
818 SYMS_U64 cie_size = 0;
820
821 // read CIE discriminator
824
825 SYMS_B32 is_fde = (fde_discrim != 0);
826 SYMS_B32 is_cie = (cie_discrim == 0);
827 if (is_fde && is_cie) {
828 void *eh_frame = (void*)((SYMS_U8*)base + eh_frame_range.min);
831
832 // parse CIE
835
836 // parse FDE
839
840 // range check instruction pointer
841 if (fde.ip_voff_range.min <= ip_voff && ip_voff < fde.ip_voff_range.max){
842 result.valid = syms_true;
843 result.cie = cie;
844 result.fde = fde;
845 }
846 }
847 }
848
849 return(result);
850}
851
852//- cfi machine
853
856 SYMS_DwCFIMachine result = {0};
857 result.cells_per_row = cells_per_row;
858 result.cie = cie;
859 result.ptr_ctx = ptr_ctx;
860 return(result);
861}
862
863SYMS_API void
865 machine->initial_row = initial_row;
866}
867
868SYMS_API void
870 machine->fde_ip = fde_ip;
871}
872
875 SYMS_DwCFIRow *result = syms_push_array(arena, SYMS_DwCFIRow, 1);
876 result->cells = syms_push_array(arena, SYMS_DwCFICell, cells_per_row);
877 return(result);
878}
879
880SYMS_API void
882 syms_memset(row->cells, 0, sizeof(*row->cells)*cells_per_row);
883 syms_memzero_struct(&row->cfa_cell);
884}
885
886SYMS_API void
888 syms_memmove(dst->cells, src->cells, sizeof(*src->cells)*cells_per_row);
889 dst->cfa_cell = src->cfa_cell;
890}
891
892
897
898 SYMS_B32 result = syms_false;
899
900 // pull out machine's equipment
901 SYMS_DwCIEUnpacked *cie = machine->cie;
902 SYMS_DwEhPtrCtx *ptr_ctx = machine->ptr_ctx;
903 SYMS_U64 cells_per_row = machine->cells_per_row;
904 SYMS_DwCFIRow *initial_row = machine->initial_row;
905
906 // start with an empty stack
908 SYMS_DwCFIRow *stack = 0;
910
911 // initialize the row
912 if (initial_row != 0){
913 syms_unwind_elf_x64__row_copy(row, initial_row, cells_per_row);
914 }
915 else{
916 syms_unwind_elf_x64__row_zero(row, cells_per_row);
917 }
918 SYMS_U64 table_ip = machine->fde_ip;
919
920 // logging
921#if SYMS_ENABLE_DEV_LOG
922 if (initial_row == 0){
923 SYMS_Log("CFA decode INIT:\n");
924 }
925 else{
926 SYMS_Log("CFA decode MAIN:\n");
927 }
928 SYMS_Log("CFA row ip: %llx\n", table_ip);
929#endif
930
931 // loop
932 SYMS_U64 cfi_off = 0;
933 for (;;){
934 // op variables
935 SYMS_DwCFA opcode = 0;
936 SYMS_U64 operand0 = 0;
937 SYMS_U64 operand1 = 0;
938 SYMS_U64 operand2 = 0;
940
941 // decode opcode/operand0
942 if (!syms_based_range_read(base, range, cfi_off, 1, &opcode)){
943 result = syms_true;
944 goto done;
945 }
946 if ((opcode & SYMS_DwCFAMask_HI_OPCODE) != 0){
950 }
951 else{
954 }
955 }
956
957 // decode operand1/operand2
959 {
960 // setup loop ins/outs
961 SYMS_U64 o[2];
962 SYMS_DwCFADecode dec[2] = {0};
963 dec[0] = (control_bits & 0xF);
964 dec[1] = ((control_bits >> 4) & 0xF);
965
966 // loop
967 SYMS_U64 *out = o;
968 for (SYMS_U64 i = 0; i < 2; i += 1, out += 1){
969 SYMS_DwCFADecode d = dec[i];
970 SYMS_U64 o_size = 0;
971 switch (d){
972 case 0:
973 {
974 *out = 0;
975 }break;
976 default:
977 {
978 if (d <= 8){
979 syms_based_range_read(base, range, decode_cursor, d, out);
980 o_size = d;
981 }
982 }break;
984 {
986 }break;
988 {
990 }break;
992 {
994 }break;
995 }
997 }
998
999 // commit out values
1000 operand1 = o[0];
1001 operand2 = o[1];
1002 }
1004
1005 // register checks
1007 if (operand0 >= cells_per_row){
1008 goto done;
1009 }
1010 }
1012 if (operand1 >= cells_per_row){
1013 goto done;
1014 }
1015 }
1017 if (operand2 >= cells_per_row){
1018 goto done;
1019 }
1020 }
1021
1022 // logging
1023#if SYMS_ENABLE_DEV_LOG
1024 {
1026 SYMS_Log("%.*s %llx %llx %llx\n", syms_expand_string(opstring), operand0, operand1, operand2);
1027 }
1028#endif
1029
1030 // values for deferred work
1032
1033 // step
1035 switch (opcode){
1036 default: goto done;
1037 case SYMS_DwCFA_NOP:break;
1038
1039
1041
1042 case SYMS_DwCFA_SET_LOC:
1043 {
1045 }break;
1047 {
1049 }break;
1051 {
1054 }break;
1055
1056
1058
1059 case SYMS_DwCFA_DEF_CFA:
1060 {
1061 row->cfa_cell.rule = SYMS_DwCFICFARule_REGOFF;
1062 row->cfa_cell.reg_idx = operand1;
1063 row->cfa_cell.offset = operand2;
1064 }break;
1065
1067 {
1068 row->cfa_cell.rule = SYMS_DwCFICFARule_REGOFF;
1069 row->cfa_cell.reg_idx = operand1;
1070 row->cfa_cell.offset = ((SYMS_S64)operand2)*cie->data_align_factor;
1071 }break;
1072
1074 {
1075 // check rule
1076 if (row->cfa_cell.rule != SYMS_DwCFICFARule_REGOFF){
1077 goto done;
1078 }
1079 // commit new cfa
1080 row->cfa_cell.reg_idx = operand1;
1081 }break;
1082
1084 {
1085 // check rule
1086 if (row->cfa_cell.rule != SYMS_DwCFICFARule_REGOFF){
1087 goto done;
1088 }
1089 // commit new cfa
1090 row->cfa_cell.offset = operand1;
1091 }break;
1092
1094 {
1095 // check rule
1096 if (row->cfa_cell.rule != SYMS_DwCFICFARule_REGOFF){
1097 goto done;
1098 }
1099 // commit new cfa
1100 row->cfa_cell.offset = ((SYMS_S64)operand1)*cie->data_align_factor;
1101 }break;
1102
1104 {
1105 // setup expr range
1109
1110 // commit new cfa
1111 row->cfa_cell.rule = SYMS_DwCFICFARule_EXPR;
1112 row->cfa_cell.expr.min = expr_first;
1113 row->cfa_cell.expr.max = expr_first + expr_size;
1114 }break;
1115
1116
1118
1120 {
1122 }break;
1123
1125 {
1127 }break;
1128
1129 case SYMS_DwCFA_OFFSET:
1130 {
1131 SYMS_DwCFICell *cell = &row->cells[operand0];
1134 }break;
1135
1137 {
1138 SYMS_DwCFICell *cell = &row->cells[operand1];
1141 }break;
1142
1144 {
1145 SYMS_DwCFICell *cell = &row->cells[operand1];
1148 }break;
1149
1151 {
1152 SYMS_DwCFICell *cell = &row->cells[operand1];
1155 }break;
1156
1158 {
1159 SYMS_DwCFICell *cell = &row->cells[operand1];
1162 }break;
1163
1165 {
1166 SYMS_DwCFICell *cell = &row->cells[operand1];
1168 cell->n = operand2;
1169 }break;
1170
1171 case SYMS_DwCFA_EXPR:
1172 {
1173 // setup expr range
1177
1178 // commit new rule
1179 SYMS_DwCFICell *cell = &row->cells[operand1];
1181 cell->expr.min = expr_first;
1182 cell->expr.max = expr_first + expr_size;
1183 }break;
1184
1186 {
1187 // setup expr range
1191
1192 // commit new rule
1193 SYMS_DwCFICell *cell = &row->cells[operand1];
1195 cell->expr.min = expr_first;
1196 cell->expr.max = expr_first + expr_size;
1197 }break;
1198
1199 case SYMS_DwCFA_RESTORE:
1200 {
1201 // check initial row
1202 if (initial_row == 0){
1203 goto done;
1204 }
1205 // commit new rule
1206 row->cells[operand0] = initial_row->cells[operand0];
1207 }break;
1208
1210 {
1211 // check initial row
1212 if (initial_row == 0){
1213 goto done;
1214 }
1215 // commit new rule
1216 row->cells[operand1] = initial_row->cells[operand1];
1217 }break;
1218
1219
1221
1223 {
1225 if (stack_row != 0){
1227 }
1228 else{
1229 stack_row = syms_unwind_elf_x64__row_alloc(scratch.arena, cells_per_row);
1230 }
1232 SYMS_StackPush(stack, stack_row);
1233 }break;
1234
1236 {
1237 if (stack != 0){
1238 SYMS_DwCFIRow *stack_row = stack;
1239 SYMS_StackPop(stack);
1242 }
1243 else{
1244 syms_unwind_elf_x64__row_zero(row, cells_per_row);
1245 }
1246 }break;
1247 }
1248
1249 // apply location change
1251 // new ip should always grow the ip
1252 if (new_table_ip <= table_ip){
1253 goto done;
1254 }
1255 // stop if this encloses the target ip
1257 result = syms_true;
1258 goto done;
1259 }
1260 // commit new ip
1262
1263 SYMS_Log("CFA row ip: %llx\n", table_ip);
1264 }
1265
1266 // advance
1268 }
1269 done:;
1270
1271 // logging
1272#if SYMS_ENABLE_DEV_LOG
1273 {
1274 switch (row->cfa_cell.rule){
1276 {
1277 SYMS_Log("CFA:(%llu, %lld); ", row->cfa_cell.reg_idx, row->cfa_cell.offset);
1278 }break;
1280 {
1281 SYMS_Log("CFA:EXPR; ");
1282 }break;
1283 }
1284 SYMS_DwCFICell *cell = row->cells;
1285 for (SYMS_U64 i = 0; i < cells_per_row; i += 1, cell += 1){
1286 SYMS_Log("[%llu]:", i);
1287 switch (cell->rule){
1289 {
1290 SYMS_Log("UNDEFINED ");
1291 }break;
1293 {
1294 SYMS_Log("SAME_VALUE ");
1295 }break;
1297 {
1298 SYMS_Log("[CFA+0x%llx] ", cell->n);
1299 }break;
1301 {
1302 SYMS_Log("(CFA+0x%llx) ", cell->n);
1303 }break;
1305 {
1306 SYMS_Log("R[%lld] ", cell->n);
1307 }break;
1309 {
1310 SYMS_Log("EXPRESSION ");
1311 }break;
1313 {
1314 SYMS_Log("VAL_EXPRESSION ");
1315 }break;
1316 }
1317 }
1318 SYMS_Log("\n");
1319 }
1320#endif
1321
1323
1324 SYMS_LogClose(log);
1325
1326 return(result);
1327}
1328
1329#endif //SYMS_UNWIND_ELF_X64_C
1330
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
char * dst
Definition lz4.h:735
float v
Definition radaudio_mdct.cpp:62
Definition syms_base.h:402
Definition syms_unwind_elf_x64.h:118
SYMS_DwCFIRegisterRule rule
Definition syms_unwind_elf_x64.h:119
Definition syms_unwind_elf_x64.h:132
SYMS_U64 fde_ip
Definition syms_unwind_elf_x64.h:137
SYMS_DwCFIRow * initial_row
Definition syms_unwind_elf_x64.h:136
SYMS_U64 cells_per_row
Definition syms_unwind_elf_x64.h:133
SYMS_DwEhPtrCtx * ptr_ctx
Definition syms_unwind_elf_x64.h:135
SYMS_DwCIEUnpacked * cie
Definition syms_unwind_elf_x64.h:134
Definition syms_unwind_elf_x64.h:86
SYMS_DwFDEUnpacked fde
Definition syms_unwind_elf_x64.h:89
SYMS_DwCIEUnpacked cie
Definition syms_unwind_elf_x64.h:88
SYMS_B32 valid
Definition syms_unwind_elf_x64.h:87
Definition syms_unwind_elf_x64.h:126
SYMS_DwCFICFACell cfa_cell
Definition syms_unwind_elf_x64.h:129
SYMS_DwCFICell * cells
Definition syms_unwind_elf_x64.h:128
Definition syms_unwind_elf_x64.h:71
SYMS_U64 offset
Definition syms_unwind_elf_x64.h:74
SYMS_DwCIEUnpacked cie
Definition syms_unwind_elf_x64.h:73
struct SYMS_DwCIEUnpackedNode * next
Definition syms_unwind_elf_x64.h:72
Definition syms_unwind_elf_x64.h:53
SYMS_S64 data_align_factor
Definition syms_unwind_elf_x64.h:63
SYMS_B8 has_augmentation_size
Definition syms_unwind_elf_x64.h:58
SYMS_DwEhPtrEnc lsda_encoding
Definition syms_unwind_elf_x64.h:55
SYMS_U8 version
Definition syms_unwind_elf_x64.h:54
SYMS_U64 code_align_factor
Definition syms_unwind_elf_x64.h:62
SYMS_DwEhPtrEnc addr_encoding
Definition syms_unwind_elf_x64.h:56
Definition syms_unwind_elf_x64.h:45
SYMS_U64 raw_base_vaddr
Definition syms_unwind_elf_x64.h:46
SYMS_U64 text_vaddr
Definition syms_unwind_elf_x64.h:47
SYMS_U64 data_vaddr
Definition syms_unwind_elf_x64.h:48
SYMS_U64 func_vaddr
Definition syms_unwind_elf_x64.h:49
Definition syms_dwarf_expr.h:83
SYMS_U64 max_step_count
Definition syms_dwarf_expr.h:85
Definition syms_unwind_elf_x64.h:78
SYMS_U64Range ip_voff_range
Definition syms_unwind_elf_x64.h:79
Definition syms_dwarf_expr.h:186
Definition syms_dwarf_expr.h:15
SYMS_U64 rip
Definition syms_dwarf_expr.h:34
SYMS_U64 r[17]
Definition syms_dwarf_expr.h:36
Definition syms_elf_parser.h:68
Definition syms_elf_parser.h:25
Definition syms_base.h:410
Definition syms_base.h:296
SYMS_U8 * str
Definition syms_base.h:297
SYMS_U64 size
Definition syms_base.h:298
Definition syms_base.h:264
SYMS_U64 max
Definition syms_base.h:266
SYMS_U64 min
Definition syms_base.h:265
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_u64_range_size(SYMS_U64Range range)
Definition syms_base.c:31
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 void syms_unwind_result_missed_read(SYMS_UnwindResult *unwind_result, SYMS_U64 addr)
Definition syms_base.c:861
SYMS_API SYMS_ArenaTemp syms_get_scratch(SYMS_Arena **conflicts, SYMS_U64 conflict_count)
Definition syms_base.c:694
SYMS_API SYMS_U64Range syms_make_u64_range(SYMS_U64 min, SYMS_U64 max)
Definition syms_base.c:18
SYMS_API SYMS_U64 syms_based_range_read_sleb128(void *base, SYMS_U64Range range, SYMS_U64 offset, SYMS_S64 *out_value)
Definition syms_base.c:792
SYMS_API SYMS_String8 syms_based_range_read_string(void *base, SYMS_U64Range range, SYMS_U64 offset)
Definition syms_base.c:823
SYMS_API SYMS_U64 syms_based_range_read_uleb128(void *base, SYMS_U64Range range, SYMS_U64 offset, SYMS_U64 *out_value)
Definition syms_base.c:765
#define syms_true
Definition syms_base.h:105
#define SYMS_StackPush(f, n)
Definition syms_base.h:227
#define syms_based_range_read_struct(b, r, o, p)
Definition syms_base.h:593
#define SYMS_U32_MAX
Definition syms_base.h:175
#define syms_push_array(a, T, c)
Definition syms_base.h:561
#define syms_memory_view_read_struct(s, a, p)
Definition syms_base.h:602
#define syms_memzero_struct(s)
Definition syms_base.h:161
#define SYMS_LOCAL
Definition syms_base.h:43
#define syms_expand_string(s)
Definition syms_base.h:484
#define syms_false
Definition syms_base.h:104
#define SYMS_API
Definition syms_base.h:29
SYMS_S32 SYMS_B32
Definition syms_base.h:99
#define SYMS_StackPop(f)
Definition syms_base.h:228
#define syms_string_from_enum_value(enum_type, value)
Definition syms_base.h:461
SYMS_S8 SYMS_B8
Definition syms_base.h:97
#define SYMS_U64_MAX
Definition syms_base.h:176
#define syms_str8_lit(s)
Definition syms_base.h:483
#define SYMS_QueuePush(f, l, n)
Definition syms_base.h:220
#define syms_release_scratch
Definition syms_base.h:567
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
int64_t SYMS_S64
Definition syms_crt_overrides.h:35
#define SYMS_S64
Definition syms_crt_overrides.h:50
#define syms_memset
Definition syms_crt_overrides.h:66
uint8_t SYMS_U8
Definition syms_crt_overrides.h:36
#define SYMS_Arena
Definition syms_default_arena.h:61
#define SYMS_LogClose(block)
Definition syms_dev.h:142
#define SYMS_LogOpen(ftr, uid, block)
Definition syms_dev.h:141
@ SYMS_LogFeature_DwarfCFIApply
Definition syms_dev.h:26
@ SYMS_LogFeature_DwarfUnwind
Definition syms_dev.h:23
@ SYMS_LogFeature_DwarfCFILookup
Definition syms_dev.h:24
@ SYMS_LogFeature_DwarfCFIDecode
Definition syms_dev.h:25
#define SYMS_Log(fmt,...)
Definition syms_dev.h:143
SYMS_API SYMS_DwLocation syms_dw_expr__eval(SYMS_Arena *arena_optional, void *expr_base, SYMS_U64Range expr_range, SYMS_DwExprMachineConfig *config)
Definition syms_dwarf_expr.c:578
@ SYMS_DwSimpleLocKind_Address
Definition syms_dwarf_expr.h:128
@ SYMS_DwSimpleLocKind_Fail
Definition syms_dwarf_expr.h:133
@ SYMS_DwLocFailKind_MissingMemory
Definition syms_dwarf_expr.h:149
SYMS_API SYMS_U64 syms_dw_based_range_read_length(void *base, SYMS_U64Range range, SYMS_U64 offset, SYMS_U64 *out_value)
Definition syms_dwarf_parser.c:427
SYMS_API SYMS_U64 syms_elf_default_vbase_from_bin(SYMS_ElfBinAccel *bin)
Definition syms_elf_parser.c:479
SYMS_API SYMS_ElfSection * syms_elf_sec_from_bin_name__unstable(SYMS_ElfBinAccel *bin, SYMS_String8 name)
Definition syms_elf_parser.c:500
@ SYMS_DwCFA_OFFSET_EXT_SF
Definition syms_meta_dwarf_cfi.h:26
@ SYMS_DwCFA_DEF_CFA_EXPR
Definition syms_meta_dwarf_cfi.h:24
@ SYMS_DwCFA_VAL_EXPR
Definition syms_meta_dwarf_cfi.h:31
@ SYMS_DwCFA_VAL_OFFSET
Definition syms_meta_dwarf_cfi.h:29
@ SYMS_DwCFA_DEF_CFA_OFFSET_SF
Definition syms_meta_dwarf_cfi.h:28
@ SYMS_DwCFA_EXPR
Definition syms_meta_dwarf_cfi.h:25
@ SYMS_DwCFA_ADVANCE_LOC
Definition syms_meta_dwarf_cfi.h:33
@ SYMS_DwCFA_UNDEFINED
Definition syms_meta_dwarf_cfi.h:16
@ SYMS_DwCFA_REGISTER
Definition syms_meta_dwarf_cfi.h:18
@ SYMS_DwCFA_RESTORE
Definition syms_meta_dwarf_cfi.h:35
@ SYMS_DwCFA_OFFSET
Definition syms_meta_dwarf_cfi.h:34
@ SYMS_DwCFA_DEF_CFA
Definition syms_meta_dwarf_cfi.h:21
@ SYMS_DwCFA_DEF_CFA_SF
Definition syms_meta_dwarf_cfi.h:27
@ SYMS_DwCFA_RESTORE_EXT
Definition syms_meta_dwarf_cfi.h:15
@ SYMS_DwCFA_VAL_OFFSET_SF
Definition syms_meta_dwarf_cfi.h:30
@ SYMS_DwCFA_ADVANCE_LOC1
Definition syms_meta_dwarf_cfi.h:11
@ SYMS_DwCFA_ADVANCE_LOC2
Definition syms_meta_dwarf_cfi.h:12
@ SYMS_DwCFA_SET_LOC
Definition syms_meta_dwarf_cfi.h:10
@ SYMS_DwCFA_NOP
Definition syms_meta_dwarf_cfi.h:9
@ SYMS_DwCFA_DEF_CFA_OFFSET
Definition syms_meta_dwarf_cfi.h:23
@ SYMS_DwCFA_SAME_VALUE
Definition syms_meta_dwarf_cfi.h:17
@ SYMS_DwCFA_RESTORE_STATE
Definition syms_meta_dwarf_cfi.h:20
@ SYMS_DwCFA_ADVANCE_LOC4
Definition syms_meta_dwarf_cfi.h:13
@ SYMS_DwCFA_OFFSET_EXT
Definition syms_meta_dwarf_cfi.h:14
@ SYMS_DwCFA_DEF_CFA_REGISTER
Definition syms_meta_dwarf_cfi.h:22
@ SYMS_DwCFA_REMEMBER_STATE
Definition syms_meta_dwarf_cfi.h:19
@ SYMS_DwCFADetail_OPL_KIND1
Definition syms_meta_dwarf_cfi.h:40
@ SYMS_DwCFAMask_HI_OPCODE
Definition syms_meta_dwarf_cfi.h:47
@ SYMS_DwCFAMask_OPERAND
Definition syms_meta_dwarf_cfi.h:48
SYMS_U8 SYMS_DwCFA
Definition syms_meta_dwarf_cfi.h:6
@ SYMS_DwRegX64_RSP
Definition syms_meta_dwarf_expr.h:64
SYMS_API void syms_unwind_elf_x64__row_copy(SYMS_DwCFIRow *dst, SYMS_DwCFIRow *src, SYMS_U64 cells_per_row)
Definition syms_unwind_elf_x64.c:887
SYMS_API SYMS_U64 syms_unwind_elf_x64__parse_pointer(void *frame_base, SYMS_U64Range frame_range, SYMS_DwEhPtrCtx *ptr_ctx, SYMS_DwEhPtrEnc encoding, SYMS_U64 off, SYMS_U64 *ptr_out)
Definition syms_unwind_elf_x64.c:359
SYMS_API void syms_unwind_elf_x64__init(void)
Definition syms_unwind_elf_x64.c:321
SYMS_API SYMS_DwCFIRecords syms_unwind_elf_x64__eh_frame_cfi_from_ip__sloppy(void *base, SYMS_U64Range range, SYMS_DwEhPtrCtx *ptr_ctx, SYMS_U64 ip_voff)
Definition syms_unwind_elf_x64.c:641
SYMS_API SYMS_DwCFIRecords syms_unwind_elf_x64__eh_frame_hdr_from_ip(void *base, SYMS_U64Range eh_frame_hdr_range, SYMS_U64Range eh_frame_range, SYMS_DwEhPtrCtx *ptr_ctx, SYMS_U64 ip_voff)
Definition syms_unwind_elf_x64.c:794
SYMS_API SYMS_UnwindResult syms_unwind_elf_x64(SYMS_String8 bin_data, SYMS_ElfBinAccel *bin, SYMS_U64 bin_base, SYMS_MemoryView *memview, SYMS_U64 stack_pointer, SYMS_DwRegsX64 *regs)
Definition syms_unwind_elf_x64.c:15
SYMS_API void syms_unwind_elf_x64__eh_frame_parse_fde(void *base, SYMS_U64Range range, SYMS_DwEhPtrCtx *ptr_ctx, SYMS_DwCIEUnpacked *cie, SYMS_U64 off, SYMS_DwFDEUnpacked *fde_out)
Definition syms_unwind_elf_x64.c:585
SYMS_API void syms_unwind_elf_x64__machine_equip_fde_ip(SYMS_DwCFIMachine *machine, SYMS_U64 fde_ip)
Definition syms_unwind_elf_x64.c:869
SYMS_API SYMS_U64 syms_search_eh_frame_hdr__linear(void *base, SYMS_U64Range range, SYMS_DwEhPtrCtx *ptr_ctx, SYMS_U64 location)
Definition syms_unwind_elf_x64.c:740
SYMS_API void syms_unwind_elf_x64__machine_equip_initial_row(SYMS_DwCFIMachine *machine, SYMS_DwCFIRow *initial_row)
Definition syms_unwind_elf_x64.c:864
SYMS_API SYMS_DwCFIMachine syms_unwind_elf_x64__machine_make(SYMS_U64 cells_per_row, SYMS_DwCIEUnpacked *cie, SYMS_DwEhPtrCtx *ptr_ctx)
Definition syms_unwind_elf_x64.c:855
SYMS_API void syms_unwind_elf_x64__row_zero(SYMS_DwCFIRow *row, SYMS_U64 cells_per_row)
Definition syms_unwind_elf_x64.c:881
SYMS_API void syms_unwind_elf_x64__eh_frame_parse_cie(void *base, SYMS_U64Range range, SYMS_DwEhPtrCtx *ptr_ctx, SYMS_U64 off, SYMS_DwCIEUnpacked *cie_out)
Definition syms_unwind_elf_x64.c:453
SYMS_API SYMS_DwCFIRow * syms_unwind_elf_x64__row_alloc(SYMS_Arena *arena, SYMS_U64 cells_per_row)
Definition syms_unwind_elf_x64.c:874
SYMS_API SYMS_B32 syms_unwind_elf_x64__machine_run_to_ip(void *base, SYMS_U64Range range, SYMS_DwCFIMachine *machine, SYMS_U64 target_ip, SYMS_DwCFIRow *row)
Definition syms_unwind_elf_x64.c:894
SYMS_API SYMS_UnwindResult syms_unwind_elf_x64__apply_rules(SYMS_String8 bin_data, SYMS_DwCFIRow *row, SYMS_U64 text_base_vaddr, SYMS_MemoryView *memview, SYMS_U64 stack_pointer, SYMS_DwRegsX64 *regs)
Definition syms_unwind_elf_x64.c:145
#define SYMS_UNWIND_ELF_X64__REG_SLOT_COUNT
Definition syms_unwind_elf_x64.h:163
SYMS_U16 SYMS_DwCFAControlBits
Definition syms_unwind_elf_x64.h:149
SYMS_U8 SYMS_DwEhPtrEnc
Definition syms_unwind_elf_x64.h:17
@ SYMS_DwEhPtrEnc_PCREL
Definition syms_unwind_elf_x64.h:33
@ SYMS_DwEhPtrEnc_MODIF_MASK
Definition syms_unwind_elf_x64.h:32
@ SYMS_DwEhPtrEnc_ALIGNED
Definition syms_unwind_elf_x64.h:37
@ SYMS_DwEhPtrEnc_DATAREL
Definition syms_unwind_elf_x64.h:35
@ SYMS_DwEhPtrEnc_FUNCREL
Definition syms_unwind_elf_x64.h:36
@ SYMS_DwEhPtrEnc_TEXTREL
Definition syms_unwind_elf_x64.h:34
@ SYMS_DwEhPtrEnc_SLEB128
Definition syms_unwind_elf_x64.h:26
@ SYMS_DwEhPtrEnc_SDATA8
Definition syms_unwind_elf_x64.h:29
@ SYMS_DwEhPtrEnc_UDATA2
Definition syms_unwind_elf_x64.h:22
@ SYMS_DwEhPtrEnc_SDATA4
Definition syms_unwind_elf_x64.h:28
@ SYMS_DwEhPtrEnc_UDATA8
Definition syms_unwind_elf_x64.h:24
@ SYMS_DwEhPtrEnc_TYPE_MASK
Definition syms_unwind_elf_x64.h:19
@ SYMS_DwEhPtrEnc_SDATA2
Definition syms_unwind_elf_x64.h:27
@ SYMS_DwEhPtrEnc_ULEB128
Definition syms_unwind_elf_x64.h:21
@ SYMS_DwEhPtrEnc_SIGNED
Definition syms_unwind_elf_x64.h:25
@ SYMS_DwEhPtrEnc_UDATA4
Definition syms_unwind_elf_x64.h:23
@ SYMS_DwEhPtrEnc_PTR
Definition syms_unwind_elf_x64.h:20
SYMS_GLOBAL SYMS_DwCFAControlBits syms_unwind_elf__cfa_control_bits_kind2[SYMS_DwCFADetail_OPL_KIND2+1]
Definition syms_unwind_elf_x64.h:160
@ SYMS_DwCFICFARule_REGOFF
Definition syms_unwind_elf_x64.h:93
@ SYMS_DwCFICFARule_EXPR
Definition syms_unwind_elf_x64.h:94
@ SYMS_DwEhPtrEnc_OMIT
Definition syms_unwind_elf_x64.h:42
SYMS_U8 SYMS_DwCFADecode
Definition syms_unwind_elf_x64.h:140
@ SYMS_DwCFADecode_ADDRESS
Definition syms_unwind_elf_x64.h:144
@ SYMS_DwCFADecode_SLEB128
Definition syms_unwind_elf_x64.h:146
@ SYMS_DwCFADecode_ULEB128
Definition syms_unwind_elf_x64.h:145
SYMS_DwCFIRegisterRule
Definition syms_unwind_elf_x64.h:108
@ SYMS_DwCFIRegisterRule_UNDEFINED
Definition syms_unwind_elf_x64.h:110
@ SYMS_DwCFIRegisterRule_EXPRESSION
Definition syms_unwind_elf_x64.h:114
@ SYMS_DwCFIRegisterRule_REGISTER
Definition syms_unwind_elf_x64.h:113
@ SYMS_DwCFIRegisterRule_SAME_VALUE
Definition syms_unwind_elf_x64.h:109
@ SYMS_DwCFIRegisterRule_VAL_OFFSET
Definition syms_unwind_elf_x64.h:112
@ SYMS_DwCFIRegisterRule_VAL_EXPRESSION
Definition syms_unwind_elf_x64.h:115
@ SYMS_DwCFIRegisterRule_OFFSET
Definition syms_unwind_elf_x64.h:111
@ SYMS_DwCFAControlBits_NEW_ROW
Definition syms_unwind_elf_x64.h:156
@ SYMS_DwCFAControlBits_IS_REG_0
Definition syms_unwind_elf_x64.h:153
@ SYMS_DwCFAControlBits_IS_REG_1
Definition syms_unwind_elf_x64.h:154
@ SYMS_DwCFAControlBits_IS_REG_2
Definition syms_unwind_elf_x64.h:155
SYMS_GLOBAL SYMS_DwCFAControlBits syms_unwind_elf__cfa_control_bits_kind1[SYMS_DwCFADetail_OPL_KIND1+1]
Definition syms_unwind_elf_x64.h:159