23
23
24
24
#include " AddressSpace.hpp"
25
25
26
+ extern " C" bool logDWARF ();
27
+
28
+ #define _LIBUNWIND_TRACE_DWARF (...) \
29
+ do { \
30
+ if (logDWARF ()) \
31
+ fprintf (stderr, __VA_ARGS__); \
32
+ } while (0 )
33
+
26
34
namespace libunwind {
27
35
28
36
// / CFI_Parser does basic parsing of a CFI (Call Frame Information) records.
@@ -364,13 +372,12 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
364
372
const CIE_Info &cieInfo, pint_t pcoffset,
365
373
PrologInfoStackEntry *&rememberStack,
366
374
PrologInfo *results) {
367
- const bool logDwarf = false ;
368
375
pint_t p = instructions;
369
376
pint_t codeOffset = 0 ;
370
377
PrologInfo initialState = *results;
371
- if (logDwarf)
372
- fprintf (stderr, " parseInstructions(instructions=0x%0" PRIx64 " )\n " ,
373
- ( uint64_t ) instructionsEnd);
378
+
379
+ _LIBUNWIND_TRACE_DWARF ( " parseInstructions(instructions=0x%0" PRIx64 " )\n " ,
380
+ static_cast < uint64_t >( instructionsEnd) );
374
381
375
382
// see DWARF Spec, section 6.4.2 for details on unwind opcodes
376
383
while ((p < instructionsEnd) && (codeOffset < pcoffset)) {
@@ -386,35 +393,30 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
386
393
++p;
387
394
switch (opcode) {
388
395
case DW_CFA_nop:
389
- if (logDwarf)
390
- fprintf (stderr, " DW_CFA_nop\n " );
396
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_nop\n " );
391
397
break ;
392
398
case DW_CFA_set_loc:
393
399
codeOffset =
394
400
addressSpace.getEncodedP (p, instructionsEnd, cieInfo.pointerEncoding );
395
- if (logDwarf)
396
- fprintf (stderr, " DW_CFA_set_loc\n " );
401
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_set_loc\n " );
397
402
break ;
398
403
case DW_CFA_advance_loc1:
399
404
codeOffset += (addressSpace.get8 (p) * cieInfo.codeAlignFactor );
400
405
p += 1 ;
401
- if (logDwarf)
402
- fprintf (stderr, " DW_CFA_advance_loc1: new offset=%" PRIu64 " \n " ,
403
- (uint64_t )codeOffset);
406
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_advance_loc1: new offset=%" PRIu64 " \n " ,
407
+ static_cast <uint64_t >(codeOffset));
404
408
break ;
405
409
case DW_CFA_advance_loc2:
406
410
codeOffset += (addressSpace.get16 (p) * cieInfo.codeAlignFactor );
407
411
p += 2 ;
408
- if (logDwarf)
409
- fprintf (stderr, " DW_CFA_advance_loc2: new offset=%" PRIu64 " \n " ,
410
- (uint64_t )codeOffset);
412
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_advance_loc2: new offset=%" PRIu64 " \n " ,
413
+ static_cast <uint64_t >(codeOffset));
411
414
break ;
412
415
case DW_CFA_advance_loc4:
413
416
codeOffset += (addressSpace.get32 (p) * cieInfo.codeAlignFactor );
414
417
p += 4 ;
415
- if (logDwarf)
416
- fprintf (stderr, " DW_CFA_advance_loc4: new offset=%" PRIu64 " \n " ,
417
- (uint64_t )codeOffset);
418
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_advance_loc4: new offset=%" PRIu64 " \n " ,
419
+ static_cast <uint64_t >(codeOffset));
418
420
break ;
419
421
case DW_CFA_offset_extended:
420
422
reg = addressSpace.getULEB128 (p, instructionsEnd);
@@ -426,21 +428,18 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
426
428
}
427
429
results->savedRegisters [reg].location = kRegisterInCFA ;
428
430
results->savedRegisters [reg].value = offset;
429
- if (logDwarf)
430
- fprintf (stderr,
431
- " DW_CFA_offset_extended(reg=%" PRIu64 " , offset=%" PRId64 " )\n " ,
432
- reg, offset);
431
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_offset_extended(reg=%" PRIu64 " , "
432
+ " offset=%" PRId64 " )\n " ,
433
+ reg, offset);
433
434
break ;
434
435
case DW_CFA_restore_extended:
435
436
reg = addressSpace.getULEB128 (p, instructionsEnd);
436
- ;
437
437
if (reg > kMaxRegisterNumber ) {
438
438
_LIBUNWIND_LOG (" malformed DWARF DW_CFA_restore_extended, reg too big" );
439
439
return false ;
440
440
}
441
441
results->savedRegisters [reg] = initialState.savedRegisters [reg];
442
- if (logDwarf)
443
- fprintf (stderr, " DW_CFA_restore_extended(reg=%" PRIu64 " )\n " , reg);
442
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_restore_extended(reg=%" PRIu64 " )\n " , reg);
444
443
break ;
445
444
case DW_CFA_undefined:
446
445
reg = addressSpace.getULEB128 (p, instructionsEnd);
@@ -449,8 +448,7 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
449
448
return false ;
450
449
}
451
450
results->savedRegisters [reg].location = kRegisterUnused ;
452
- if (logDwarf)
453
- fprintf (stderr, " DW_CFA_undefined(reg=%" PRIu64 " )\n " , reg);
451
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_undefined(reg=%" PRIu64 " )\n " , reg);
454
452
break ;
455
453
case DW_CFA_same_value:
456
454
reg = addressSpace.getULEB128 (p, instructionsEnd);
@@ -465,8 +463,7 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
465
463
results->savedRegisters [reg].location = kRegisterUnused ;
466
464
// set flag to disable conversion to compact unwind
467
465
results->sameValueUsed = true ;
468
- if (logDwarf)
469
- fprintf (stderr, " DW_CFA_same_value(reg=%" PRIu64 " )\n " , reg);
466
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_same_value(reg=%" PRIu64 " )\n " , reg);
470
467
break ;
471
468
case DW_CFA_register:
472
469
reg = addressSpace.getULEB128 (p, instructionsEnd);
@@ -483,9 +480,8 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
483
480
results->savedRegisters [reg].value = (int64_t )reg2;
484
481
// set flag to disable conversion to compact unwind
485
482
results->registersInOtherRegisters = true ;
486
- if (logDwarf)
487
- fprintf (stderr, " DW_CFA_register(reg=%" PRIu64 " , reg2=%" PRIu64 " )\n " ,
488
- reg, reg2);
483
+ _LIBUNWIND_TRACE_DWARF (
484
+ " DW_CFA_register(reg=%" PRIu64 " , reg2=%" PRIu64 " )\n " , reg, reg2);
489
485
break ;
490
486
#if !defined(_LIBUNWIND_NO_HEAP)
491
487
case DW_CFA_remember_state:
@@ -498,8 +494,7 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
498
494
} else {
499
495
return false ;
500
496
}
501
- if (logDwarf)
502
- fprintf (stderr, " DW_CFA_remember_state\n " );
497
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_remember_state\n " );
503
498
break ;
504
499
case DW_CFA_restore_state:
505
500
if (rememberStack != NULL ) {
@@ -510,8 +505,7 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
510
505
} else {
511
506
return false ;
512
507
}
513
- if (logDwarf)
514
- fprintf (stderr, " DW_CFA_restore_state\n " );
508
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_restore_state\n " );
515
509
break ;
516
510
#endif
517
511
case DW_CFA_def_cfa:
@@ -523,9 +517,8 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
523
517
}
524
518
results->cfaRegister = (uint32_t )reg;
525
519
results->cfaRegisterOffset = (int32_t )offset;
526
- if (logDwarf)
527
- fprintf (stderr, " DW_CFA_def_cfa(reg=%" PRIu64 " , offset=%" PRIu64 " )\n " ,
528
- reg, offset);
520
+ _LIBUNWIND_TRACE_DWARF (
521
+ " DW_CFA_def_cfa(reg=%" PRIu64 " , offset=%" PRIu64 " )\n " , reg, offset);
529
522
break ;
530
523
case DW_CFA_def_cfa_register:
531
524
reg = addressSpace.getULEB128 (p, instructionsEnd);
@@ -534,26 +527,23 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
534
527
return false ;
535
528
}
536
529
results->cfaRegister = (uint32_t )reg;
537
- if (logDwarf)
538
- fprintf (stderr, " DW_CFA_def_cfa_register(%" PRIu64 " )\n " , reg);
530
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_def_cfa_register(%" PRIu64 " )\n " , reg);
539
531
break ;
540
532
case DW_CFA_def_cfa_offset:
541
533
results->cfaRegisterOffset = (int32_t )
542
534
addressSpace.getULEB128 (p, instructionsEnd);
543
535
results->codeOffsetAtStackDecrement = (uint32_t )codeOffset;
544
- if (logDwarf)
545
- fprintf (stderr, " DW_CFA_def_cfa_offset(%d)\n " ,
546
- results->cfaRegisterOffset );
536
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_def_cfa_offset(%d)\n " ,
537
+ results->cfaRegisterOffset );
547
538
break ;
548
539
case DW_CFA_def_cfa_expression:
549
540
results->cfaRegister = 0 ;
550
541
results->cfaExpression = (int64_t )p;
551
542
length = addressSpace.getULEB128 (p, instructionsEnd);
552
543
p += length;
553
- if (logDwarf)
554
- fprintf (stderr, " DW_CFA_def_cfa_expression(expression=0x%" PRIx64
555
- " , length=%" PRIu64 " )\n " ,
556
- results->cfaExpression , length);
544
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_def_cfa_expression(expression=0x%" PRIx64
545
+ " , length=%" PRIu64 " )\n " ,
546
+ results->cfaExpression , length);
557
547
break ;
558
548
case DW_CFA_expression:
559
549
reg = addressSpace.getULEB128 (p, instructionsEnd);
@@ -565,10 +555,10 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
565
555
results->savedRegisters [reg].value = (int64_t )p;
566
556
length = addressSpace.getULEB128 (p, instructionsEnd);
567
557
p += length;
568
- if (logDwarf)
569
- fprintf (stderr, " DW_CFA_expression(reg= %" PRIu64
570
- " , expression=0x% " PRIx64 " , length=%" PRIu64 " )\n " ,
571
- reg, results->savedRegisters [reg].value , length);
558
+ _LIBUNWIND_TRACE_DWARF ( " DW_CFA_expression(reg=% " PRIu64 " , "
559
+ " expression=0x %" PRIx64 " , "
560
+ " length=%" PRIu64 " )\n " ,
561
+ reg, results->savedRegisters [reg].value , length);
572
562
break ;
573
563
case DW_CFA_offset_extended_sf:
574
564
reg = addressSpace.getULEB128 (p, instructionsEnd);
@@ -581,10 +571,9 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
581
571
addressSpace.getSLEB128 (p, instructionsEnd) * cieInfo.dataAlignFactor ;
582
572
results->savedRegisters [reg].location = kRegisterInCFA ;
583
573
results->savedRegisters [reg].value = offset;
584
- if (logDwarf)
585
- fprintf (stderr, " DW_CFA_offset_extended_sf(reg=%" PRIu64
586
- " , offset=%" PRId64 " )\n " ,
587
- reg, offset);
574
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_offset_extended_sf(reg=%" PRIu64 " , "
575
+ " offset=%" PRId64 " )\n " ,
576
+ reg, offset);
588
577
break ;
589
578
case DW_CFA_def_cfa_sf:
590
579
reg = addressSpace.getULEB128 (p, instructionsEnd);
@@ -596,29 +585,26 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
596
585
}
597
586
results->cfaRegister = (uint32_t )reg;
598
587
results->cfaRegisterOffset = (int32_t )offset;
599
- if (logDwarf)
600
- fprintf (stderr,
601
- " DW_CFA_def_cfa_sf(reg=%" PRIu64 " , offset=%" PRId64 " )\n " , reg,
602
- offset);
588
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_def_cfa_sf(reg=%" PRIu64 " , "
589
+ " offset=%" PRId64 " )\n " ,
590
+ reg, offset);
603
591
break ;
604
592
case DW_CFA_def_cfa_offset_sf:
605
593
results->cfaRegisterOffset = (int32_t )
606
594
(addressSpace.getSLEB128 (p, instructionsEnd) * cieInfo.dataAlignFactor );
607
595
results->codeOffsetAtStackDecrement = (uint32_t )codeOffset;
608
- if (logDwarf)
609
- fprintf (stderr, " DW_CFA_def_cfa_offset_sf(%d)\n " ,
610
- results->cfaRegisterOffset );
596
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_def_cfa_offset_sf(%d)\n " ,
597
+ results->cfaRegisterOffset );
611
598
break ;
612
599
case DW_CFA_val_offset:
613
600
reg = addressSpace.getULEB128 (p, instructionsEnd);
614
601
offset = (int64_t )addressSpace.getULEB128 (p, instructionsEnd)
615
602
* cieInfo.dataAlignFactor ;
616
603
results->savedRegisters [reg].location = kRegisterOffsetFromCFA ;
617
604
results->savedRegisters [reg].value = offset;
618
- if (logDwarf)
619
- fprintf (stderr,
620
- " DW_CFA_val_offset(reg=%" PRIu64 " , offset=%" PRId64 " \n " , reg,
621
- offset);
605
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_val_offset(reg=%" PRIu64 " , "
606
+ " offset=%" PRId64 " \n " ,
607
+ reg, offset);
622
608
break ;
623
609
case DW_CFA_val_offset_sf:
624
610
reg = addressSpace.getULEB128 (p, instructionsEnd);
@@ -630,10 +616,9 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
630
616
addressSpace.getSLEB128 (p, instructionsEnd) * cieInfo.dataAlignFactor ;
631
617
results->savedRegisters [reg].location = kRegisterOffsetFromCFA ;
632
618
results->savedRegisters [reg].value = offset;
633
- if (logDwarf)
634
- fprintf (stderr,
635
- " DW_CFA_val_offset_sf(reg=%" PRIu64 " , offset=%" PRId64 " \n " ,
636
- reg, offset);
619
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_val_offset_sf(reg=%" PRIu64 " , "
620
+ " offset=%" PRId64 " \n " ,
621
+ reg, offset);
637
622
break ;
638
623
case DW_CFA_val_expression:
639
624
reg = addressSpace.getULEB128 (p, instructionsEnd);
@@ -645,16 +630,14 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
645
630
results->savedRegisters [reg].value = (int64_t )p;
646
631
length = addressSpace.getULEB128 (p, instructionsEnd);
647
632
p += length;
648
- if (logDwarf)
649
- fprintf (stderr, " DW_CFA_val_expression(reg=%" PRIu64
650
- " , expression=0x%" PRIx64 " , length=%" PRIu64 " )\n " ,
651
- reg, results->savedRegisters [reg].value , length);
633
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_val_expression(reg=%" PRIu64 " , "
634
+ " expression=0x%" PRIx64 " , length=%" PRIu64 " )\n " ,
635
+ reg, results->savedRegisters [reg].value , length);
652
636
break ;
653
637
case DW_CFA_GNU_args_size:
654
638
length = addressSpace.getULEB128 (p, instructionsEnd);
655
639
results->spExtraArgSize = (uint32_t )length;
656
- if (logDwarf)
657
- fprintf (stderr, " DW_CFA_GNU_args_size(%" PRIu64 " )\n " , length);
640
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_GNU_args_size(%" PRIu64 " )\n " , length);
658
641
break ;
659
642
case DW_CFA_GNU_negative_offset_extended:
660
643
reg = addressSpace.getULEB128 (p, instructionsEnd);
@@ -667,9 +650,8 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
667
650
* cieInfo.dataAlignFactor ;
668
651
results->savedRegisters [reg].location = kRegisterInCFA ;
669
652
results->savedRegisters [reg].value = -offset;
670
- if (logDwarf)
671
- fprintf (stderr, " DW_CFA_GNU_negative_offset_extended(%" PRId64 " )\n " ,
672
- offset);
653
+ _LIBUNWIND_TRACE_DWARF (
654
+ " DW_CFA_GNU_negative_offset_extended(%" PRId64 " )\n " , offset);
673
655
break ;
674
656
default :
675
657
operand = opcode & 0x3F ;
@@ -680,25 +662,22 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
680
662
* cieInfo.dataAlignFactor ;
681
663
results->savedRegisters [reg].location = kRegisterInCFA ;
682
664
results->savedRegisters [reg].value = offset;
683
- if (logDwarf)
684
- fprintf (stderr, " DW_CFA_offset(reg=%d, offset=%" PRId64 " )\n " ,
685
- operand, offset);
665
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_offset(reg=%d, offset=%" PRId64 " )\n " ,
666
+ operand, offset);
686
667
break ;
687
668
case DW_CFA_advance_loc:
688
669
codeOffset += operand * cieInfo.codeAlignFactor ;
689
- if (logDwarf)
690
- fprintf (stderr, " DW_CFA_advance_loc: new offset=%" PRIu64 " \n " ,
691
- (uint64_t )codeOffset);
670
+ _LIBUNWIND_TRACE_DWARF (" DW_CFA_advance_loc: new offset=%" PRIu64 " \n " ,
671
+ static_cast <uint64_t >(codeOffset));
692
672
break ;
693
673
case DW_CFA_restore:
694
674
reg = operand;
695
675
results->savedRegisters [reg] = initialState.savedRegisters [reg];
696
- if (logDwarf)
697
- fprintf (stderr, " DW_CFA_restore(reg=% " PRIu64 " ) \n " , reg );
676
+ _LIBUNWIND_TRACE_DWARF ( " DW_CFA_restore(reg=% " PRIu64 " ) \n " ,
677
+ static_cast < long >(operand) );
698
678
break ;
699
679
default :
700
- if (logDwarf)
701
- fprintf (stderr, " unknown CFA opcode 0x%02X\n " , opcode);
680
+ _LIBUNWIND_TRACE_DWARF (" unknown CFA opcode 0x%02X\n " , opcode);
702
681
return false ;
703
682
}
704
683
}
0 commit comments