dwarf4.cpp
Go to the documentation of this file.
1 //
2 // Bareflank Unwind Library
3 //
4 // Copyright (C) 2015 Assured Information Security, Inc.
5 // Author: Rian Quinn <quinnr@ainfosec.com>
6 // Author: Brendan Kerrigan <kerriganb@ainfosec.com>
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 
22 #include <misc.h>
23 #include <abort.h>
24 #include <dwarf4.h>
25 
26 // -----------------------------------------------------------------------------
27 // Helpers
28 // -----------------------------------------------------------------------------
29 
30 template<typename T> T static get(char **p)
31 { auto v = *reinterpret_cast<T *>(*p); (*p) += sizeof(T); return v;}
32 
33 // TODO: We should attempt to convert these to lambda functions in the
34 // future as clang-tidy is getting upset about "b" not being enclosed
35 // in a (). Converting these to functions that take a lambda should
36 // remove the need for a macro. To do this, a couple of things will
37 // need to be done:
38 // - An opcode -> str function will be needed as we currently leverage
39 // the macro to stringify the opcodes
40 // - The embedded return / continue will need to be removed, which will
41 // help with reability in some ways, but hurt in others.
42 // - Remove the exception from clang-tidy once this is addressed.
43 
44 #define REMEMBER_STACK_SIZE 10
45 #define EXPRESSION_STACK_SIZE 100
46 
47 // -----------------------------------------------------------------------------
48 // Call Frame Information (CFI) Register
49 // -----------------------------------------------------------------------------
50 
51 class cfi_register
52 {
53 public:
54  cfi_register() :
55  m_index(0),
56  m_rule(rule_undefined),
57  m_value(0)
58  {}
59 
60  cfi_register(uint64_t index, register_rules rule, uint64_t value) :
61  m_index(index),
62  m_rule(rule),
63  m_value(value)
64  {}
65 
66  uint64_t index() const
67  { return m_index; }
68 
69  register_rules rule() const
70  { return m_rule; }
71 
72  uint64_t value() const
73  { return m_value; }
74 
75  void set_index(uint64_t index)
76  { m_index = index; }
77 
78  void set_rule(register_rules rule)
79  { m_rule = rule; }
80 
81  void set_value(uint64_t value)
82  { m_value = value; }
83 
84 private:
85  uint64_t m_index;
86  register_rules m_rule;
87  uint64_t m_value;
88 };
89 
90 // -----------------------------------------------------------------------------
91 // Call Frame Information (CFI) Canonical Frame Address (CFA)
92 // -----------------------------------------------------------------------------
93 
94 class cfi_cfa
95 {
96 public:
97 
98  enum cfi_cfa_type
99  {
100  cfa_register = 1,
101  cfa_expression = 2,
102  };
103 
104 public:
105  cfi_cfa() :
106  m_value(0),
107  m_offset(0),
108  m_type(cfa_register)
109  {}
110 
111  uint64_t value() const
112  { return m_value; }
113 
114  int64_t offset() const
115  { return m_offset; }
116 
117  cfi_cfa_type type() const
118  { return m_type; }
119 
120  void set_value(uint64_t value)
121  { m_value = value; }
122 
123  void set_offset(int64_t offset)
124  { m_offset = offset; }
125 
126  void set_type(cfi_cfa_type type)
127  { m_type = type; }
128 
129 private:
130  uint64_t m_value;
131  int64_t m_offset;
132  cfi_cfa_type m_type;
133 };
134 
135 // -----------------------------------------------------------------------------
136 // Call Frame Information (CFI) Table Row
137 // -----------------------------------------------------------------------------
138 
139 class cfi_table_row
140 {
141 public:
142  cfi_table_row() :
143  m_arg_size(0)
144  {
145  for (auto i = 0U; i < MAX_NUM_REGISTERS; i++)
146  m_registers[i].set_index(i);
147  }
148 
149  const cfi_cfa &cfa() const
150  { return m_cfa; }
151 
152  uint64_t arg_size() const
153  { return m_arg_size; }
154 
155  const cfi_register &reg(uint64_t index) const
156  {
157  if (index >= MAX_NUM_REGISTERS)
158  ABORT("index out of bounds. increase MAX_NUM_REGISTERS");
159 
160  return m_registers[index];
161  }
162 
163  void set_cfa(const cfi_cfa &cfa)
164  { m_cfa = cfa; }
165 
166  void set_arg_size(uint64_t arg_size)
167  { m_arg_size = arg_size; }
168 
169  void set_reg(const cfi_register &reg)
170  {
171  if (reg.index() >= MAX_NUM_REGISTERS)
172  ABORT("index out of bounds. increase MAX_NUM_REGISTERS");
173 
174  m_registers[reg.index()] = reg;
175  }
176 
177  void set_reg(uint64_t index, register_rules rule)
178  {
179  if (index >= MAX_NUM_REGISTERS)
180  ABORT("index out of bounds. increase MAX_NUM_REGISTERS");
181 
182  m_registers[index].set_rule(rule);
183  }
184 
185  void set_reg(uint64_t index, uint64_t value)
186  {
187  if (index >= MAX_NUM_REGISTERS)
188  ABORT("index out of bounds. increase MAX_NUM_REGISTERS");
189 
190  m_registers[index].set_value(value);
191  }
192 
193 private:
194  cfi_cfa m_cfa;
195  uint64_t m_arg_size;
196  cfi_register m_registers[MAX_NUM_REGISTERS];
197 };
198 
199 // -----------------------------------------------------------------------------
200 // Unwind Helpers
201 // -----------------------------------------------------------------------------
202 
203 // TODO: In the future, the stack should be implemented using a custom C++
204 // class that guards [] to prevent the stack variable from being
205 // accessed out of bounds
206 
207 static uint64_t
208 private_parse_expression(char *p,
209  uint64_t initialStackValue,
210  register_state *state)
211 {
212  uint64_t i = 0;
213  uint64_t stack[EXPRESSION_STACK_SIZE];
214 
215  stack[i] = initialStackValue;
216 
217  char *end = p + dwarf4::decode_uleb128(&p);
218 
219  while (p <= end)
220  {
221  uint8_t opcode = *reinterpret_cast<uint8_t *>(p);
222  p++;
223 
224  if (i >= EXPRESSION_STACK_SIZE - 1)
225  ABORT("out of DWARF expression stack space");
226 
227  switch (opcode)
228  {
229  case DW_OP_addr:
230  {
231  stack[++i] = *reinterpret_cast<uint64_t *>(p);
232  p += sizeof(uint64_t);
233  break;
234  }
235 
236  case DW_OP_deref:
237  {
238  if (stack[i] == 0)
239  ABORT("DW_OP_deref: attempted to dereference nullptr");
240 
241  stack[i] = *reinterpret_cast<uint64_t *>(stack[i]);
242  break;
243  }
244 
245  case DW_OP_const1u:
246  {
247  stack[++i] = static_cast<uint64_t>(*reinterpret_cast<uint8_t *>(p));
248  p += sizeof(uint8_t);
249  break;
250  }
251 
252  case DW_OP_const1s:
253  {
254  stack[++i] = static_cast<uint64_t>(*reinterpret_cast<int8_t *>(p));
255  p += sizeof(int8_t);
256  break;
257  }
258 
259  case DW_OP_const2u:
260  {
261  stack[++i] = static_cast<uint64_t>(*reinterpret_cast<uint16_t *>(p));
262  p += sizeof(uint16_t);
263  break;
264  }
265 
266  case DW_OP_const2s:
267  {
268  stack[++i] = static_cast<uint64_t>(*reinterpret_cast<int16_t *>(p));
269  p += sizeof(int16_t);
270  break;
271  }
272 
273  case DW_OP_const4u:
274  {
275  stack[++i] = static_cast<uint64_t>(*reinterpret_cast<uint32_t *>(p));
276  p += sizeof(uint32_t);
277  break;
278  }
279 
280  case DW_OP_const4s:
281  {
282  stack[++i] = static_cast<uint64_t>(*reinterpret_cast<int32_t *>(p));
283  p += sizeof(int32_t);
284  break;
285  }
286 
287  case DW_OP_const8u:
288  {
289  stack[++i] = *reinterpret_cast<uint64_t *>(p);
290  p += sizeof(uint64_t);
291  break;
292  }
293 
294  case DW_OP_const8s:
295  {
296  stack[++i] = static_cast<uint64_t>(*reinterpret_cast<int64_t *>(p));
297  p += sizeof(int64_t);
298  break;
299  }
300 
301  case DW_OP_constu:
302  {
303  stack[++i] = dwarf4::decode_uleb128(&p);
304  break;
305  }
306 
307  case DW_OP_consts:
308  {
309  stack[++i] = static_cast<uint64_t>(dwarf4::decode_sleb128(&p));
310  break;
311  }
312 
313  case DW_OP_dup:
314  {
315  auto value = stack[i];
316  stack[++i] = value;
317  break;
318  }
319 
320  case DW_OP_drop:
321  {
322  if (i == 0)
323  ABORT("DW_OP_drop out-of-bounds");
324  i--;
325  break;
326  }
327 
328  case DW_OP_over:
329  {
330  if (i == 0)
331  ABORT("DW_OP_over out-of-bounds");
332  auto value = stack[i - 1];
333  stack[++i] = value;
334  break;
335  }
336 
337  case DW_OP_pick:
338  {
339  auto index = *reinterpret_cast<uint8_t *>(p);
340  p += sizeof(uint8_t);
341 
342  if (index > i)
343  ABORT("DW_OP_pick out-of-bounds");
344 
345  auto value = stack[i - index];
346  stack[++i] = value;
347  break;
348  }
349 
350  case DW_OP_swap:
351  {
352  if (i == 0)
353  ABORT("DW_OP_swap out-of-bounds");
354 
355  auto value = stack[i];
356  stack[i] = stack[i - 1];
357  stack[i - 1] = value;
358  break;
359  }
360 
361  case DW_OP_rot:
362  {
363  if (i <= 1)
364  ABORT("DW_OP_swap out-of-bounds");
365 
366  auto value = stack[i];
367  stack[i] = stack[i - 1];
368  stack[i - 1] = stack[i - 2];
369  stack[i - 2] = value;
370  break;
371  }
372 
373  case DW_OP_xderef:
374  {
375  if (i == 0)
376  ABORT("DW_OP_xderef out-of-bounds");
377 
378  auto value = stack[i--];
379 
380  if (value == 0)
381  ABORT("DW_OP_deref: attempted to dereference nullptr");
382 
383  stack[i] = *reinterpret_cast<uint64_t *>(value);
384  break;
385  }
386 
387  case DW_OP_abs:
388  {
389  auto value = static_cast<int64_t>(stack[i]);
390  if (value < 0)
391  stack[i] = static_cast<uint64_t>(-value);
392  break;
393  }
394 
395  case DW_OP_and:
396  {
397  if (i == 0)
398  ABORT("DW_OP_and out-of-bounds");
399 
400  auto value = stack[i--];
401  stack[i] &= value;
402  break;
403  }
404 
405  case DW_OP_minus:
406  {
407  if (i == 0)
408  ABORT("DW_OP_minus out-of-bounds");
409 
410  auto value = stack[i--];
411  stack[i] -= value;
412  break;
413  }
414 
415  case DW_OP_mul:
416  {
417  if (i == 0)
418  ABORT("DW_OP_minus out-of-bounds");
419 
420  auto value = stack[i--];
421  stack[i] *= value;
422  break;
423  }
424 
425  case DW_OP_neg:
426  {
427  stack[i] = static_cast<uint64_t>(0 - static_cast<int64_t>(stack[i]));
428  break;
429  }
430 
431  case DW_OP_not:
432  {
433  stack[i] = ~stack[i];
434  break;
435  }
436 
437  case DW_OP_or:
438  {
439  if (i == 0)
440  ABORT("DW_OP_or out-of-bounds");
441 
442  auto value = stack[i--];
443  stack[i] |= value;
444  break;
445  }
446 
447  case DW_OP_plus:
448  {
449  if (i == 0)
450  ABORT("DW_OP_plus out-of-bounds");
451 
452  auto value = stack[i--];
453  stack[i] += value;
454  break;
455  }
456 
457  case DW_OP_plus_uconst:
458  {
459  stack[i] += dwarf4::decode_uleb128(&p);
460  break;
461  }
462 
463  case DW_OP_shl:
464  {
465  if (i == 0)
466  ABORT("DW_OP_shl out-of-bounds");
467 
468  auto value = stack[i--];
469  stack[i] = stack[i] << value;
470  break;
471  }
472 
473  case DW_OP_shr:
474  {
475  if (i == 0)
476  ABORT("DW_OP_shr out-of-bounds");
477 
478  auto value = stack[i--];
479  stack[i] = stack[i] >> value;
480  break;
481  }
482 
483  case DW_OP_shra:
484  {
485  if (i == 0)
486  ABORT("DW_OP_shra out-of-bounds");
487 
488  auto value1 = stack[i--];
489  auto value2 = static_cast<int64_t>(stack[i]);
490  stack[i] = static_cast<uint64_t>(value2 >> value1);
491  break;
492  }
493 
494  case DW_OP_xor:
495  {
496  if (i == 0)
497  ABORT("DW_OP_xor out-of-bounds");
498 
499  auto value = stack[i--];
500  stack[i] ^= value;
501  break;
502  }
503 
504  case DW_OP_skip:
505  {
506  auto value = *reinterpret_cast<int16_t *>(p);
507  p += 2;
508  p += value;
509  break;
510  }
511 
512  case DW_OP_bra:
513  {
514  if (i == 0)
515  ABORT("DW_OP_bra out-of-bounds");
516 
517  auto value = *reinterpret_cast<int16_t *>(p);
518  p += 2;
519  if (stack[i--] != 0)
520  p += value;
521  break;
522  }
523 
524  case DW_OP_eq:
525  {
526  if (i == 0)
527  ABORT("DW_OP_eq out-of-bounds");
528 
529  auto value = stack[i--];
530  stack[i] = (stack[i] == value) ? 1 : 0;
531  break;
532  }
533 
534  case DW_OP_ge:
535  {
536  if (i == 0)
537  ABORT("DW_OP_ge out-of-bounds");
538 
539  auto value = stack[i--];
540  stack[i] = (stack[i] >= value) ? 1 : 0;
541  break;
542  }
543 
544  case DW_OP_gt:
545  {
546  if (i == 0)
547  ABORT("DW_OP_gt out-of-bounds");
548 
549  auto value = stack[i--];
550  stack[i] = (stack[i] > value) ? 1 : 0;
551  break;
552  }
553 
554  case DW_OP_le:
555  {
556  if (i == 0)
557  ABORT("DW_OP_le out-of-bounds");
558 
559  auto value = stack[i--];
560  stack[i] = (stack[i] <= value) ? 1 : 0;
561  break;
562  }
563 
564  case DW_OP_lt:
565  {
566  if (i == 0)
567  ABORT("DW_OP_lt out-of-bounds");
568 
569  auto value = stack[i--];
570  stack[i] = (stack[i] < value) ? 1 : 0;
571  break;
572  }
573 
574  case DW_OP_ne:
575  {
576  if (i == 0)
577  ABORT("DW_OP_ne out-of-bounds");
578 
579  auto value = stack[i--];
580  stack[i] = (stack[i] != value) ? 1 : 0;
581  break;
582  }
583 
584  case DW_OP_lit0:
585  {
586  stack[++i] = 0;
587  break;
588  }
589 
590  case DW_OP_lit1:
591  {
592  stack[++i] = 1;
593  break;
594  }
595 
596  case DW_OP_lit2:
597  {
598  stack[++i] = 2;
599  break;
600  }
601 
602  case DW_OP_lit3:
603  {
604  stack[++i] = 3;
605  break;
606  }
607 
608  case DW_OP_lit4:
609  {
610  stack[++i] = 4;
611  break;
612  }
613 
614  case DW_OP_lit5:
615  {
616  stack[++i] = 5;
617  break;
618  }
619 
620  case DW_OP_lit6:
621  {
622  stack[++i] = 6;
623  break;
624  }
625 
626  case DW_OP_lit7:
627  {
628  stack[++i] = 7;
629  break;
630  }
631 
632  case DW_OP_lit8:
633  {
634  stack[++i] = 8;
635  break;
636  }
637 
638  case DW_OP_lit9:
639  {
640  stack[++i] = 9;
641  break;
642  }
643 
644  case DW_OP_lit10:
645  {
646  stack[++i] = 10;
647  break;
648  }
649 
650  case DW_OP_lit11:
651  {
652  stack[++i] = 11;
653  break;
654  }
655 
656  case DW_OP_lit12:
657  {
658  stack[++i] = 12;
659  break;
660  }
661 
662  case DW_OP_lit13:
663  {
664  stack[++i] = 13;
665  break;
666  }
667 
668  case DW_OP_lit14:
669  {
670  stack[++i] = 14;
671  break;
672  }
673 
674  case DW_OP_lit15:
675  {
676  stack[++i] = 15;
677  break;
678  }
679 
680  case DW_OP_lit16:
681  {
682  stack[++i] = 16;
683  break;
684  }
685 
686  case DW_OP_lit17:
687  {
688  stack[++i] = 17;
689  break;
690  }
691 
692  case DW_OP_lit18:
693  {
694  stack[++i] = 18;
695  break;
696  }
697 
698  case DW_OP_lit19:
699  {
700  stack[++i] = 19;
701  break;
702  }
703 
704  case DW_OP_lit20:
705  {
706  stack[++i] = 20;
707  break;
708  }
709 
710  case DW_OP_lit21:
711  {
712  stack[++i] = 21;
713  break;
714  }
715 
716  case DW_OP_lit22:
717  {
718  stack[++i] = 22;
719  break;
720  }
721 
722  case DW_OP_lit23:
723  {
724  stack[++i] = 23;
725  break;
726  }
727 
728  case DW_OP_lit24:
729  {
730  stack[++i] = 24;
731  break;
732  }
733 
734  case DW_OP_lit25:
735  {
736  stack[++i] = 25;
737  break;
738  }
739 
740  case DW_OP_lit26:
741  {
742  stack[++i] = 26;
743  break;
744  }
745 
746  case DW_OP_lit27:
747  {
748  stack[++i] = 27;
749  break;
750  }
751 
752  case DW_OP_lit28:
753  {
754  stack[++i] = 28;
755  break;
756  }
757 
758  case DW_OP_lit29:
759  {
760  stack[++i] = 29;
761  break;
762  }
763 
764  case DW_OP_lit30:
765  {
766  stack[++i] = 30;
767  break;
768  }
769 
770  case DW_OP_lit31:
771  {
772  stack[++i] = 31;
773  break;
774  }
775 
776  case DW_OP_reg0:
777  {
778  stack[++i] = state->get(0);
779  break;
780  }
781 
782  case DW_OP_reg1:
783  {
784  stack[++i] = state->get(1);
785  break;
786  }
787 
788  case DW_OP_reg2:
789  {
790  stack[++i] = state->get(2);
791  break;
792  }
793 
794  case DW_OP_reg3:
795  {
796  stack[++i] = state->get(3);
797  break;
798  }
799 
800  case DW_OP_reg4:
801  {
802  stack[++i] = state->get(4);
803  break;
804  }
805 
806  case DW_OP_reg5:
807  {
808  stack[++i] = state->get(5);
809  break;
810  }
811 
812  case DW_OP_reg6:
813  {
814  stack[++i] = state->get(6);
815  break;
816  }
817 
818  case DW_OP_reg7:
819  {
820  stack[++i] = state->get(7);
821  break;
822  }
823 
824  case DW_OP_reg8:
825  {
826  stack[++i] = state->get(8);
827  break;
828  }
829 
830  case DW_OP_reg9:
831  {
832  stack[++i] = state->get(9);
833  break;
834  }
835 
836  case DW_OP_reg10:
837  {
838  stack[++i] = state->get(10);
839  break;
840  }
841 
842  case DW_OP_reg11:
843  {
844  stack[++i] = state->get(11);
845  break;
846  }
847 
848  case DW_OP_reg12:
849  {
850  stack[++i] = state->get(12);
851  break;
852  }
853 
854  case DW_OP_reg13:
855  {
856  stack[++i] = state->get(13);
857  break;
858  }
859 
860  case DW_OP_reg14:
861  {
862  stack[++i] = state->get(14);
863  break;
864  }
865 
866  case DW_OP_reg15:
867  {
868  stack[++i] = state->get(15);
869  break;
870  }
871 
872  case DW_OP_reg16:
873  {
874  stack[++i] = state->get(16);
875  break;
876  }
877 
878  case DW_OP_reg17:
879  {
880  stack[++i] = state->get(17);
881  break;
882  }
883 
884  case DW_OP_reg18:
885  {
886  stack[++i] = state->get(18);
887  break;
888  }
889 
890  case DW_OP_reg19:
891  {
892  stack[++i] = state->get(19);
893  break;
894  }
895 
896  case DW_OP_reg20:
897  {
898  stack[++i] = state->get(20);
899  break;
900  }
901 
902  case DW_OP_reg21:
903  {
904  stack[++i] = state->get(21);
905  break;
906  }
907 
908  case DW_OP_reg22:
909  {
910  stack[++i] = state->get(22);
911  break;
912  }
913 
914  case DW_OP_reg23:
915  {
916  stack[++i] = state->get(23);
917  break;
918  }
919 
920  case DW_OP_reg24:
921  {
922  stack[++i] = state->get(24);
923  break;
924  }
925 
926  case DW_OP_reg25:
927  {
928  stack[++i] = state->get(25);
929  break;
930  }
931 
932  case DW_OP_reg26:
933  {
934  stack[++i] = state->get(26);
935  break;
936  }
937 
938  case DW_OP_reg27:
939  {
940  stack[++i] = state->get(27);
941  break;
942  }
943 
944  case DW_OP_reg28:
945  {
946  stack[++i] = state->get(28);
947  break;
948  }
949 
950  case DW_OP_reg29:
951  {
952  stack[++i] = state->get(29);
953  break;
954  }
955 
956  case DW_OP_reg30:
957  {
958  stack[++i] = state->get(30);
959  break;
960  }
961 
962  case DW_OP_reg31:
963  {
964  stack[++i] = state->get(31);
965  break;
966  }
967 
968  case DW_OP_breg0:
969  {
970  auto reg = state->get(0);
971  auto offset = dwarf4::decode_sleb128(&p);
972  stack[++i] = add_offset(reg, offset);
973  break;
974  }
975 
976  case DW_OP_breg1:
977  {
978  auto reg = state->get(1);
979  auto offset = dwarf4::decode_sleb128(&p);
980  stack[++i] = add_offset(reg, offset);
981  break;
982  }
983 
984  case DW_OP_breg2:
985  {
986  auto reg = state->get(2);
987  auto offset = dwarf4::decode_sleb128(&p);
988  stack[++i] = add_offset(reg, offset);
989  break;
990  }
991 
992  case DW_OP_breg3:
993  {
994  auto reg = state->get(3);
995  auto offset = dwarf4::decode_sleb128(&p);
996  stack[++i] = add_offset(reg, offset);
997  break;
998  }
999 
1000  case DW_OP_breg4:
1001  {
1002  auto reg = state->get(4);
1003  auto offset = dwarf4::decode_sleb128(&p);
1004  stack[++i] = add_offset(reg, offset);
1005  break;
1006  }
1007 
1008  case DW_OP_breg5:
1009  {
1010  auto reg = state->get(5);
1011  auto offset = dwarf4::decode_sleb128(&p);
1012  stack[++i] = add_offset(reg, offset);
1013  break;
1014  }
1015 
1016  case DW_OP_breg6:
1017  {
1018  auto reg = state->get(6);
1019  auto offset = dwarf4::decode_sleb128(&p);
1020  stack[++i] = add_offset(reg, offset);
1021  break;
1022  }
1023 
1024  case DW_OP_breg7:
1025  {
1026  auto reg = state->get(7);
1027  auto offset = dwarf4::decode_sleb128(&p);
1028  stack[++i] = add_offset(reg, offset);
1029  break;
1030  }
1031 
1032  case DW_OP_breg8:
1033  {
1034  auto reg = state->get(8);
1035  auto offset = dwarf4::decode_sleb128(&p);
1036  stack[++i] = add_offset(reg, offset);
1037  break;
1038  }
1039 
1040  case DW_OP_breg9:
1041  {
1042  auto reg = state->get(9);
1043  auto offset = dwarf4::decode_sleb128(&p);
1044  stack[++i] = add_offset(reg, offset);
1045  break;
1046  }
1047 
1048  case DW_OP_breg10:
1049  {
1050  auto reg = state->get(10);
1051  auto offset = dwarf4::decode_sleb128(&p);
1052  stack[++i] = add_offset(reg, offset);
1053  break;
1054  }
1055 
1056  case DW_OP_breg11:
1057  {
1058  auto reg = state->get(11);
1059  auto offset = dwarf4::decode_sleb128(&p);
1060  stack[++i] = add_offset(reg, offset);
1061  break;
1062  }
1063 
1064  case DW_OP_breg12:
1065  {
1066  auto reg = state->get(12);
1067  auto offset = dwarf4::decode_sleb128(&p);
1068  stack[++i] = add_offset(reg, offset);
1069  break;
1070  }
1071 
1072  case DW_OP_breg13:
1073  {
1074  auto reg = state->get(13);
1075  auto offset = dwarf4::decode_sleb128(&p);
1076  stack[++i] = add_offset(reg, offset);
1077  break;
1078  }
1079 
1080  case DW_OP_breg14:
1081  {
1082  auto reg = state->get(14);
1083  auto offset = dwarf4::decode_sleb128(&p);
1084  stack[++i] = add_offset(reg, offset);
1085  break;
1086  }
1087 
1088  case DW_OP_breg15:
1089  {
1090  auto reg = state->get(15);
1091  auto offset = dwarf4::decode_sleb128(&p);
1092  stack[++i] = add_offset(reg, offset);
1093  break;
1094  }
1095 
1096  case DW_OP_breg16:
1097  {
1098  auto reg = state->get(16);
1099  auto offset = dwarf4::decode_sleb128(&p);
1100  stack[++i] = add_offset(reg, offset);
1101  break;
1102  }
1103 
1104  case DW_OP_breg17:
1105  {
1106  auto reg = state->get(17);
1107  auto offset = dwarf4::decode_sleb128(&p);
1108  stack[++i] = add_offset(reg, offset);
1109  break;
1110  }
1111 
1112  case DW_OP_breg18:
1113  {
1114  auto reg = state->get(18);
1115  auto offset = dwarf4::decode_sleb128(&p);
1116  stack[++i] = add_offset(reg, offset);
1117  break;
1118  }
1119 
1120  case DW_OP_breg19:
1121  {
1122  auto reg = state->get(19);
1123  auto offset = dwarf4::decode_sleb128(&p);
1124  stack[++i] = add_offset(reg, offset);
1125  break;
1126  }
1127 
1128  case DW_OP_breg20:
1129  {
1130  auto reg = state->get(20);
1131  auto offset = dwarf4::decode_sleb128(&p);
1132  stack[++i] = add_offset(reg, offset);
1133  break;
1134  }
1135 
1136  case DW_OP_breg21:
1137  {
1138  auto reg = state->get(21);
1139  auto offset = dwarf4::decode_sleb128(&p);
1140  stack[++i] = add_offset(reg, offset);
1141  break;
1142  }
1143 
1144  case DW_OP_breg22:
1145  {
1146  auto reg = state->get(22);
1147  auto offset = dwarf4::decode_sleb128(&p);
1148  stack[++i] = add_offset(reg, offset);
1149  break;
1150  }
1151 
1152  case DW_OP_breg23:
1153  {
1154  auto reg = state->get(23);
1155  auto offset = dwarf4::decode_sleb128(&p);
1156  stack[++i] = add_offset(reg, offset);
1157  break;
1158  }
1159 
1160  case DW_OP_breg24:
1161  {
1162  auto reg = state->get(24);
1163  auto offset = dwarf4::decode_sleb128(&p);
1164  stack[++i] = add_offset(reg, offset);
1165  break;
1166  }
1167 
1168  case DW_OP_breg25:
1169  {
1170  auto reg = state->get(25);
1171  auto offset = dwarf4::decode_sleb128(&p);
1172  stack[++i] = add_offset(reg, offset);
1173  break;
1174  }
1175 
1176  case DW_OP_breg26:
1177  {
1178  auto reg = state->get(26);
1179  auto offset = dwarf4::decode_sleb128(&p);
1180  stack[++i] = add_offset(reg, offset);
1181  break;
1182  }
1183 
1184  case DW_OP_breg27:
1185  {
1186  auto reg = state->get(27);
1187  auto offset = dwarf4::decode_sleb128(&p);
1188  stack[++i] = add_offset(reg, offset);
1189  break;
1190  }
1191 
1192  case DW_OP_breg28:
1193  {
1194  auto reg = state->get(28);
1195  auto offset = dwarf4::decode_sleb128(&p);
1196  stack[++i] = add_offset(reg, offset);
1197  break;
1198  }
1199 
1200  case DW_OP_breg29:
1201  {
1202  auto reg = state->get(29);
1203  auto offset = dwarf4::decode_sleb128(&p);
1204  stack[++i] = add_offset(reg, offset);
1205  break;
1206  }
1207 
1208  case DW_OP_breg30:
1209  {
1210  auto reg = state->get(30);
1211  auto offset = dwarf4::decode_sleb128(&p);
1212  stack[++i] = add_offset(reg, offset);
1213  break;
1214  }
1215 
1216  case DW_OP_breg31:
1217  {
1218  auto reg = state->get(31);
1219  auto offset = dwarf4::decode_sleb128(&p);
1220  stack[++i] = add_offset(reg, offset);
1221  break;
1222  }
1223 
1224  case DW_OP_regx:
1225  {
1226  stack[++i] = state->get(dwarf4::decode_uleb128(&p));
1227  break;
1228  }
1229 
1230  case DW_OP_bregx:
1231  {
1232  stack[++i] = state->get(dwarf4::decode_uleb128(&p));
1233  stack[i] = add_offset(stack[i], dwarf4::decode_sleb128(&p));
1234  break;
1235  }
1236 
1237  case DW_OP_deref_size:
1238  {
1239  if (stack[i] == 0)
1240  ABORT("DW_OP_deref: attempted to dereference nullptr");
1241 
1242  switch (*reinterpret_cast<uint8_t *>(p++))
1243  {
1244  case 1:
1245  stack[i] = *reinterpret_cast<uint8_t *>(stack[i]);
1246  break;
1247 
1248  case 2:
1249  stack[i] = *reinterpret_cast<uint16_t *>(stack[i]);
1250  break;
1251 
1252  case 4:
1253  stack[i] = *reinterpret_cast<uint32_t *>(stack[i]);
1254  break;
1255 
1256  case 8:
1257  stack[i] = *reinterpret_cast<uint64_t *>(stack[i]);
1258  break;
1259 
1260  default:
1261  ABORT("DW_OP_deref_size: invalid size");
1262  }
1263 
1264  break;
1265  }
1266 
1267  default:
1268  ABORT("DWARF expression opcode not supported");
1269  }
1270  }
1271 
1272  return stack[i];
1273 }
1274 
1275 static uint64_t
1276 private_decode_cfa(const cfi_table_row &row, register_state *state)
1277 {
1278  uint64_t value = 0;
1279  const auto &cfa = row.cfa();
1280 
1281  switch (cfa.type())
1282  {
1283  case cfi_cfa::cfa_register:
1284  value = add_offset(state->get(cfa.value()), cfa.offset());
1285  break;
1286 
1287  case cfi_cfa::cfa_expression:
1288  value = private_parse_expression(reinterpret_cast<char *>(cfa.value()), 0, state);
1289  break;
1290  }
1291 
1292  return value;
1293 }
1294 
1295 static uint64_t
1296 private_decode_reg(const cfi_register &reg, uint64_t cfa, register_state *state)
1297 {
1298  uint64_t value = 0;
1299 
1300  switch (reg.rule())
1301  {
1302  case rule_undefined:
1303  ABORT("unable to get register value for unused register");
1304  break;
1305 
1306  case rule_same_value:
1307  value = state->get(reg.index());
1308  break;
1309 
1310  case rule_offsetn:
1311  value = *reinterpret_cast<uint64_t *>(add_offset(cfa, static_cast<int64_t>(reg.value())));
1312  break;
1313 
1314  case rule_val_offsetn:
1315  value = add_offset(cfa, static_cast<int64_t>(reg.value()));
1316  break;
1317 
1318  case rule_register:
1319  value = state->get(reg.value());
1320  break;
1321 
1322  case rule_expression:
1323  value = private_parse_expression(reinterpret_cast<char *>(reg.value()), cfa, state);
1324  value = *reinterpret_cast<uint64_t *>(value);
1325  break;
1326 
1327  case rule_val_expression:
1328  value = private_parse_expression(reinterpret_cast<char *>(reg.value()), cfa, state);
1329  break;
1330 
1331  default:
1332  ABORT("unknown rule. cfi table is malformed");
1333  }
1334 
1335  return value;
1336 }
1337 
1338 void
1339 private_parse_instruction(cfi_table_row *row,
1340  const ci_entry &cie,
1341  char **p,
1342  uint64_t *l1,
1343  uint64_t *l2,
1344  uint64_t pc_begin,
1345  register_state *state,
1346  uint64_t &rememberIndex,
1347  cfi_table_row *rememberStack,
1348  cfi_table_row *initialRow)
1349 {
1350  (void) l1;
1351  (void) pc_begin;
1352  (void) state;
1353 
1354  uint8_t opcode = *reinterpret_cast<uint8_t *>(*p) & 0xC0;
1355  uint8_t operand = *reinterpret_cast<uint8_t *>(*p) & 0x3F;
1356 
1357  if (opcode == 0)
1358  opcode = operand;
1359 
1360  (*p)++;
1361 
1362  switch (opcode)
1363  {
1364  case DW_CFA_advance_loc:
1365  {
1366  *l2 += static_cast<uint64_t>(operand) * cie.code_alignment();
1367  break;
1368  }
1369 
1370  case DW_CFA_offset:
1371  {
1372  auto value = static_cast<int64_t>(dwarf4::decode_uleb128(p)) * cie.data_alignment();
1373  row->set_reg(cfi_register(operand, rule_offsetn, static_cast<uint64_t>(value)));
1374  break;
1375  }
1376 
1377  case DW_CFA_restore:
1378  {
1379  row->set_reg(initialRow->reg(operand));
1380  break;
1381  }
1382 
1383  case DW_CFA_nop:
1384  {
1385  break;
1386  }
1387 
1388  case DW_CFA_set_loc:
1389  {
1390  *l2 = decode_pointer(p, cie.pointer_encoding());
1391  break;
1392  }
1393 
1394  case DW_CFA_advance_loc1:
1395  {
1396  *l2 += get<uint8_t>(p) * cie.code_alignment();
1397  break;
1398  }
1399 
1400  case DW_CFA_advance_loc2:
1401  {
1402  *l2 += get<uint16_t>(p) * cie.code_alignment();
1403  break;
1404  }
1405 
1406  case DW_CFA_advance_loc4:
1407  {
1408  *l2 += get<uint32_t>(p) * cie.code_alignment();
1409  break;
1410  }
1411 
1413  {
1414  auto reg = dwarf4::decode_uleb128(p);
1415  auto value = static_cast<int64_t>(dwarf4::decode_uleb128(p)) * cie.data_alignment();
1416  row->set_reg(cfi_register(reg, rule_offsetn, static_cast<uint64_t>(value)));
1417  break;
1418  }
1419 
1421  {
1422  auto reg = dwarf4::decode_uleb128(p);
1423  row->set_reg(initialRow->reg(reg));
1424  break;
1425  }
1426 
1427  case DW_CFA_undefined:
1428  {
1429  auto reg = dwarf4::decode_uleb128(p);
1430  row->set_reg(reg, rule_undefined);
1431  break;
1432  }
1433 
1434  case DW_CFA_same_value:
1435  {
1436  auto reg = dwarf4::decode_uleb128(p);
1437  row->set_reg(reg, rule_same_value);
1438  break;
1439  }
1440 
1441  case DW_CFA_register:
1442  {
1443  auto reg1 = dwarf4::decode_uleb128(p);
1444  auto reg2 = dwarf4::decode_uleb128(p);
1445  row->set_reg(reg1, row->reg(reg2).rule());
1446  break;
1447  }
1448 
1449  case DW_CFA_remember_state:
1450  {
1451  if (rememberIndex >= REMEMBER_STACK_SIZE)
1452  ABORT("remember stack is full. unable to continue unwind");
1453 
1454  rememberStack[rememberIndex++] = *row;
1455  break;
1456  }
1457 
1458  case DW_CFA_restore_state:
1459  {
1460  if (rememberIndex == 0)
1461  ABORT("remember stack is empty. unable to continue unwind");
1462 
1463  *row = rememberStack[--rememberIndex];
1464  break;
1465  }
1466 
1467  case DW_CFA_def_cfa:
1468  {
1469  auto cfa = row->cfa();
1470  cfa.set_value(dwarf4::decode_uleb128(p));
1471  cfa.set_offset(static_cast<int64_t>(dwarf4::decode_uleb128(p)));
1472  row->set_cfa(cfa);
1473  break;
1474  }
1475 
1477  {
1478  auto cfa = row->cfa();
1479  cfa.set_value(dwarf4::decode_uleb128(p));
1480  row->set_cfa(cfa);
1481  break;
1482  }
1483 
1484  case DW_CFA_def_cfa_offset:
1485  {
1486  auto cfa = row->cfa();
1487  cfa.set_offset(static_cast<int64_t>(dwarf4::decode_uleb128(p)));
1488  row->set_cfa(cfa);
1489  break;
1490  }
1491 
1493  {
1494  auto cfa = row->cfa();
1495  cfa.set_value(reinterpret_cast<uint64_t>(*p));
1496  cfa.set_type(cfi_cfa::cfa_expression);
1497  row->set_cfa(cfa);
1498  *p += dwarf4::decode_uleb128(p);
1499  break;
1500  }
1501 
1502  case DW_CFA_expression:
1503  {
1504  auto reg = dwarf4::decode_uleb128(p);
1505  auto value = reinterpret_cast<uint64_t>(*p);
1506  row->set_reg(cfi_register(reg, rule_expression, value));
1507  *p += dwarf4::decode_uleb128(p);
1508  break;
1509  }
1510 
1512  {
1513  auto reg = dwarf4::decode_uleb128(p);
1514  auto value = dwarf4::decode_sleb128(p) * cie.data_alignment();
1515  row->set_reg(cfi_register(reg, rule_offsetn, static_cast<uint64_t>(value)));
1516  break;
1517  }
1518 
1519  case DW_CFA_def_cfa_sf:
1520  {
1521  auto cfa = row->cfa();
1522  cfa.set_value(dwarf4::decode_uleb128(p));
1523  cfa.set_offset(dwarf4::decode_sleb128(p) * cie.data_alignment());
1524  row->set_cfa(cfa);
1525  break;
1526  }
1527 
1529  {
1530  auto cfa = row->cfa();
1531  cfa.set_offset(dwarf4::decode_sleb128(p) * cie.data_alignment());
1532  row->set_cfa(cfa);
1533  break;
1534  }
1535 
1536  case DW_CFA_val_offset:
1537  {
1538  auto reg = dwarf4::decode_uleb128(p);
1539  auto value = static_cast<int64_t>(dwarf4::decode_uleb128(p)) * cie.data_alignment();
1540  row->set_reg(cfi_register(reg, rule_val_offsetn, static_cast<uint64_t>(value)));
1541  break;
1542  }
1543 
1544  case DW_CFA_val_offset_sf:
1545  {
1546  auto reg = dwarf4::decode_uleb128(p);
1547  auto value = dwarf4::decode_sleb128(p) * cie.data_alignment();
1548  row->set_reg(cfi_register(reg, rule_val_offsetn, static_cast<uint64_t>(value)));
1549  break;
1550  }
1551 
1552  case DW_CFA_val_expression:
1553  {
1554  auto reg = dwarf4::decode_uleb128(p);
1555  auto value = reinterpret_cast<uint64_t>(*p);
1556  row->set_reg(cfi_register(reg, rule_val_expression, value));
1557  *p += dwarf4::decode_uleb128(p);
1558  break;
1559  }
1560 
1561  case DW_CFA_GNU_args_size:
1562  {
1563  auto arg_size = dwarf4::decode_uleb128(p);
1564  row->set_arg_size(arg_size);
1565  break;
1566  }
1567 
1569  {
1570  auto reg = dwarf4::decode_uleb128(p);
1571  auto value = static_cast<int64_t>(dwarf4::decode_uleb128(p)) * cie.data_alignment();
1572  row->set_reg(cfi_register(reg, rule_offsetn, static_cast<uint64_t>(-value)));
1573  break;
1574  }
1575 
1576  default:
1577  ABORT("unknown cfi cfa");
1578  }
1579 }
1580 
1581 static void
1582 private_parse_instructions(cfi_table_row *row,
1583  const ci_entry &cie,
1584  const fd_entry &fde,
1585  register_state *state,
1586  bool is_cie)
1587 {
1588  uint64_t pc_begin = is_cie ? 0 : fde.pc_begin();
1589  uint64_t l1 = is_cie ? 0ULL : state->get_ip() - fde.pc_begin();
1590  uint64_t l2 = 0ULL;
1591 
1592  char *p = is_cie ? cie.initial_instructions() : fde.instructions();
1593  char *end = is_cie ? cie.entry_end() : fde.entry_end();
1594 
1595  uint64_t rememberIndex = 0ULL;
1596  cfi_table_row rememberStack[REMEMBER_STACK_SIZE] = {};
1597 
1598  auto initialRow = *row;
1599 
1600  while (p < end && l1 >= l2)
1601  private_parse_instruction(row, cie, &p, &l1, &l2, pc_begin, state,
1602  rememberIndex, rememberStack, &initialRow);
1603 }
1604 
1605 cfi_table_row
1607 {
1608  auto row = cfi_table_row();
1609  const auto &cie = fde.cie();
1610 
1611  private_parse_instructions(&row, cie, fde, state, true);
1612  private_parse_instructions(&row, cie, fde, state, false);
1613 
1614  return row;
1615 }
1616 
1617 // -----------------------------------------------------------------------------
1618 // DWARF 4 Implementation
1619 // -----------------------------------------------------------------------------
1620 
1621 int64_t
1623 {
1624  int64_t byte = 0;
1625  int64_t shift = 0;
1626  int64_t result = 0;
1627 
1628  while (true)
1629  {
1630  byte = *(reinterpret_cast<uint8_t *>((*addr)++));
1631  result |= ((byte & 0x7f) << shift);
1632  shift += 7;
1633  if ((byte & 0x80) == 0)
1634  break;
1635  }
1636 
1637  if ((shift < 0x40) && (byte & 0x40) != 0)
1638  result |= -(1LL << shift);
1639 
1640  return result;
1641 }
1642 
1643 uint64_t
1645 {
1646  uint64_t byte = 0;
1647  uint64_t shift = 0;
1648  uint64_t result = 0;
1649 
1650  while (true)
1651  {
1652  byte = *(reinterpret_cast<uint8_t *>((*addr)++));
1653  result |= ((byte & 0x7f) << shift);
1654  shift += 7;
1655  if ((byte & 0x80) == 0)
1656  break;
1657  }
1658 
1659  return result;
1660 }
1661 
1662 #ifndef __clang__
1663 #pragma GCC diagnostic push
1664 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
1665 #endif
1666 
1667 void
1669 {
1670  if (state == nullptr)
1671  return;
1672 
1673  auto row = private_decode_cfi(fde, state);
1674  auto cfa = private_decode_cfa(row, state);
1675 
1676  for (auto i = 0U; i < state->max_num_registers(); i++)
1677  {
1678  auto reg = row.reg(i);
1679 
1680  if (reg.rule() == rule_undefined)
1681  continue;
1682 
1683  state->set(i, private_decode_reg(reg, cfa, state));
1684  }
1685 
1686  state->commit(cfa + row.arg_size());
1687 }
1688 
1689 #ifndef __clang__
1690 #pragma GCC diagnostic pop
1691 #endif
#define DW_CFA_same_value
Definition: dwarf4.h:169
static void unwind(const fd_entry &fde, register_state *state=nullptr)
Definition: dwarf4.cpp:1668
#define DW_OP_reg2
Definition: dwarf4.h:261
#define DW_OP_breg21
Definition: dwarf4.h:312
#define DW_OP_constu
Definition: dwarf4.h:195
#define DW_OP_reg24
Definition: dwarf4.h:283
#define DW_OP_breg15
Definition: dwarf4.h:306
const ci_entry & cie() const
Definition: eh_frame.h:603
#define DW_OP_reg5
Definition: dwarf4.h:264
#define DW_OP_breg3
Definition: dwarf4.h:294
#define DW_OP_breg5
Definition: dwarf4.h:296
#define DW_CFA_nop
Definition: dwarf4.h:161
#define DW_OP_minus
Definition: dwarf4.h:207
#define DW_OP_breg28
Definition: dwarf4.h:319
#define DW_OP_breg23
Definition: dwarf4.h:314
#define DW_OP_lit17
Definition: dwarf4.h:244
#define DW_OP_lit19
Definition: dwarf4.h:246
#define DW_OP_breg17
Definition: dwarf4.h:308
#define DW_OP_shra
Definition: dwarf4.h:217
#define DW_OP_breg27
Definition: dwarf4.h:318
#define DW_OP_reg10
Definition: dwarf4.h:269
#define DW_OP_breg11
Definition: dwarf4.h:302
#define DW_OP_regx
Definition: dwarf4.h:323
#define DW_OP_breg13
Definition: dwarf4.h:304
#define DW_OP_reg0
Definition: dwarf4.h:259
#define DW_OP_reg17
Definition: dwarf4.h:276
#define DW_OP_const4u
Definition: dwarf4.h:191
#define DW_OP_reg25
Definition: dwarf4.h:284
#define DW_OP_lit9
Definition: dwarf4.h:236
#define DW_CFA_val_expression
Definition: dwarf4.h:183
#define MAX_NUM_REGISTERS
Definition: registers.h:27
static uint64_t decode_uleb128(char **addr)
Definition: dwarf4.cpp:1644
#define DW_OP_breg14
Definition: dwarf4.h:305
uint64_t pc_begin() const
Definition: eh_frame.h:573
uint64_t pointer_encoding() const
Definition: eh_frame.h:449
#define DW_OP_lit13
Definition: dwarf4.h:240
#define DW_OP_not
Definition: dwarf4.h:211
#define DW_OP_neg
Definition: dwarf4.h:210
#define DW_CFA_val_offset_sf
Definition: dwarf4.h:182
#define DW_CFA_set_loc
Definition: dwarf4.h:162
#define DW_OP_lit23
Definition: dwarf4.h:250
char * entry_end() const
Definition: eh_frame.h:299
#define DW_OP_xderef
Definition: dwarf4.h:203
cfi_table_row private_decode_cfi(const fd_entry &fde, register_state *state)
Definition: dwarf4.cpp:1606
#define DW_OP_over
Definition: dwarf4.h:199
#define DW_OP_lt
Definition: dwarf4.h:225
#define DW_CFA_expression
Definition: dwarf4.h:177
#define DW_CFA_restore_state
Definition: dwarf4.h:172
#define ABORT(a)
Definition: abort.h:51
#define DW_OP_ge
Definition: dwarf4.h:222
#define DW_OP_gt
Definition: dwarf4.h:223
#define DW_OP_breg18
Definition: dwarf4.h:309
#define DW_OP_bra
Definition: dwarf4.h:220
#define DW_OP_rot
Definition: dwarf4.h:202
#define DW_OP_reg12
Definition: dwarf4.h:271
#define DW_OP_lit0
Definition: dwarf4.h:227
#define DW_OP_reg27
Definition: dwarf4.h:286
#define DW_OP_lit21
Definition: dwarf4.h:248
#define DW_OP_reg19
Definition: dwarf4.h:278
#define DW_OP_breg29
Definition: dwarf4.h:320
Definition: eh_frame.h:360
#define DW_OP_reg20
Definition: dwarf4.h:279
#define DW_OP_lit31
Definition: dwarf4.h:258
#define DW_OP_reg16
Definition: dwarf4.h:275
register_rules
Definition: dwarf4.h:143
#define DW_OP_const8s
Definition: dwarf4.h:194
#define DW_OP_lit14
Definition: dwarf4.h:241
static int64_t decode_sleb128(char **addr)
Definition: dwarf4.cpp:1622
#define DW_OP_bregx
Definition: dwarf4.h:325
#define DW_OP_breg1
Definition: dwarf4.h:292
char * initial_instructions() const
Definition: eh_frame.h:480
#define DW_CFA_def_cfa_offset
Definition: dwarf4.h:175
#define DW_CFA_register
Definition: dwarf4.h:170
void private_parse_instruction(cfi_table_row *row, const ci_entry &cie, char **p, uint64_t *l1, uint64_t *l2, uint64_t pc_begin, register_state *state, uint64_t &rememberIndex, cfi_table_row *rememberStack, cfi_table_row *initialRow)
Definition: dwarf4.cpp:1339
#define DW_OP_breg8
Definition: dwarf4.h:299
#define DW_OP_const1u
Definition: dwarf4.h:187
#define DW_CFA_offset_extended
Definition: dwarf4.h:166
#define DW_CFA_def_cfa_register
Definition: dwarf4.h:174
#define DW_OP_plus_uconst
Definition: dwarf4.h:214
#define DW_CFA_offset_extended_sf
Definition: dwarf4.h:178
#define DW_OP_reg30
Definition: dwarf4.h:289
#define DW_OP_lit1
Definition: dwarf4.h:228
uint64_t add_offset(uint64_t value, int64_t offset)
Definition: misc.h:32
#define DW_OP_lit25
Definition: dwarf4.h:252
virtual uint64_t max_num_registers() const
Definition: registers.h:138
#define DW_OP_breg2
Definition: dwarf4.h:293
#define DW_OP_breg9
Definition: dwarf4.h:300
virtual uint64_t get(uint64_t index) const
Definition: registers.h:94
#define DW_OP_breg6
Definition: dwarf4.h:297
#define DW_OP_lit4
Definition: dwarf4.h:231
#define DW_OP_reg6
Definition: dwarf4.h:265
#define DW_OP_lit24
Definition: dwarf4.h:251
#define DW_OP_breg0
Definition: dwarf4.h:291
auto index(const T virt, const F from)
constexpr const auto addr
Definition: cpuid_x64.h:80
#define DW_OP_breg7
Definition: dwarf4.h:298
#define DW_OP_lit15
Definition: dwarf4.h:242
#define DW_OP_mul
Definition: dwarf4.h:209
#define DW_OP_lit10
Definition: dwarf4.h:237
#define DW_CFA_GNU_negative_offset_extended
Definition: eh_frame.h:148
#define DW_OP_reg3
Definition: dwarf4.h:262
#define DW_OP_lit3
Definition: dwarf4.h:230
uint64_t decode_pointer(char **addr, uint64_t encoding)
Definition: eh_frame.cpp:33
#define DW_OP_abs
Definition: dwarf4.h:204
#define DW_CFA_advance_loc4
Definition: dwarf4.h:165
#define DW_CFA_def_cfa_sf
Definition: dwarf4.h:179
uint64_t code_alignment() const
Definition: eh_frame.h:423
#define DW_OP_reg23
Definition: dwarf4.h:282
#define DW_OP_dup
Definition: dwarf4.h:197
#define DW_CFA_offset
Definition: dwarf4.h:159
#define DW_OP_reg9
Definition: dwarf4.h:268
#define DW_OP_or
Definition: dwarf4.h:212
#define DW_OP_lit27
Definition: dwarf4.h:254
#define DW_OP_consts
Definition: dwarf4.h:196
#define DW_OP_and
Definition: dwarf4.h:205
#define DW_OP_deref_size
Definition: dwarf4.h:327
#define DW_CFA_advance_loc1
Definition: dwarf4.h:163
#define DW_OP_plus
Definition: dwarf4.h:213
#define DW_CFA_def_cfa_offset_sf
Definition: dwarf4.h:180
#define DW_OP_skip
Definition: dwarf4.h:219
#define DW_OP_breg10
Definition: dwarf4.h:301
#define DW_OP_reg7
Definition: dwarf4.h:266
#define DW_OP_lit2
Definition: dwarf4.h:229
#define DW_OP_lit29
Definition: dwarf4.h:256
#define DW_OP_reg29
Definition: dwarf4.h:288
#define EXPRESSION_STACK_SIZE
Definition: dwarf4.cpp:45
#define DW_OP_reg4
Definition: dwarf4.h:263
#define DW_CFA_def_cfa
Definition: dwarf4.h:173
#define DW_OP_lit12
Definition: dwarf4.h:239
#define DW_OP_ne
Definition: dwarf4.h:226
#define DW_OP_breg22
Definition: dwarf4.h:313
#define DW_OP_lit7
Definition: dwarf4.h:234
#define DW_OP_reg11
Definition: dwarf4.h:270
#define DW_OP_breg12
Definition: dwarf4.h:303
#define DW_OP_pick
Definition: dwarf4.h:200
#define DW_OP_reg26
Definition: dwarf4.h:285
#define DW_OP_breg25
Definition: dwarf4.h:316
#define DW_OP_shl
Definition: dwarf4.h:215
#define DW_OP_reg8
Definition: dwarf4.h:267
#define DW_OP_breg31
Definition: dwarf4.h:322
#define DW_OP_breg26
Definition: dwarf4.h:317
virtual void commit()
Definition: registers.h:113
virtual register_state & set(uint64_t index, uint64_t value)
Definition: registers.h:106
#define DW_OP_shr
Definition: dwarf4.h:216
#define DW_OP_const2u
Definition: dwarf4.h:189
#define DW_OP_const1s
Definition: dwarf4.h:188
#define DW_OP_reg15
Definition: dwarf4.h:274
#define DW_OP_xor
Definition: dwarf4.h:218
#define DW_OP_breg16
Definition: dwarf4.h:307
#define DW_OP_breg19
Definition: dwarf4.h:310
#define DW_CFA_val_offset
Definition: dwarf4.h:181
#define DW_OP_lit22
Definition: dwarf4.h:249
#define DW_OP_drop
Definition: dwarf4.h:198
#define DW_OP_lit16
Definition: dwarf4.h:243
#define DW_OP_lit26
Definition: dwarf4.h:253
#define DW_OP_reg18
Definition: dwarf4.h:277
#define DW_CFA_remember_state
Definition: dwarf4.h:171
#define DW_OP_addr
Definition: dwarf4.h:185
#define DW_OP_const2s
Definition: dwarf4.h:190
char * instructions() const
Definition: eh_frame.h:596
#define DW_OP_breg30
Definition: dwarf4.h:321
auto end(reversed_container< T > container) -> decltype(container.container.rend())
Definition: reverse.h:43
#define DW_OP_eq
Definition: dwarf4.h:221
#define DW_OP_lit8
Definition: dwarf4.h:235
#define DW_CFA_advance_loc
Definition: dwarf4.h:158
#define DW_OP_deref
Definition: dwarf4.h:186
#define DW_OP_swap
Definition: dwarf4.h:201
#define DW_OP_lit18
Definition: dwarf4.h:245
#define DW_CFA_def_cfa_expression
Definition: dwarf4.h:176
#define DW_OP_lit20
Definition: dwarf4.h:247
#define DW_OP_reg14
Definition: dwarf4.h:273
#define DW_OP_lit28
Definition: dwarf4.h:255
#define DW_OP_reg21
Definition: dwarf4.h:280
#define offset(a, b)
Definition: test.cpp:192
#define DW_OP_breg4
Definition: dwarf4.h:295
Definition: eh_frame.h:510
#define REMEMBER_STACK_SIZE
Definition: dwarf4.cpp:44
virtual uint64_t get_ip() const
Definition: registers.h:75
int64_t data_alignment() const
Definition: eh_frame.h:432
#define DW_CFA_restore_extended
Definition: dwarf4.h:167
#define DW_OP_le
Definition: dwarf4.h:224
#define DW_OP_lit11
Definition: dwarf4.h:238
#define DW_OP_reg31
Definition: dwarf4.h:290
#define DW_OP_reg28
Definition: dwarf4.h:287
#define DW_OP_reg13
Definition: dwarf4.h:272
#define DW_OP_lit5
Definition: dwarf4.h:232
#define DW_CFA_GNU_args_size
Definition: eh_frame.h:147
#define DW_OP_const4s
Definition: dwarf4.h:192
#define DW_CFA_advance_loc2
Definition: dwarf4.h:164
#define DW_OP_breg20
Definition: dwarf4.h:311
#define DW_OP_reg22
Definition: dwarf4.h:281
#define DW_OP_lit30
Definition: dwarf4.h:257
#define DW_CFA_restore
Definition: dwarf4.h:160
#define DW_OP_breg24
Definition: dwarf4.h:315
#define DW_OP_const8u
Definition: dwarf4.h:193
#define DW_OP_lit6
Definition: dwarf4.h:233
#define DW_OP_reg1
Definition: dwarf4.h:260
#define DW_CFA_undefined
Definition: dwarf4.h:168