Changeset 75235 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Nov 2, 2018 9:01:36 PM (6 years ago)
- Location:
- trunk/src/VBox/Runtime/common
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp
r75163 r75235 46 46 #include <iprt/string.h> 47 47 #include <iprt/strcache.h> 48 #include <iprt/x86.h> 48 49 #include "internal/dbgmod.h" 49 50 … … 395 396 #define DW_CFA_offset_extended_sf UINT8_C(0x11) /**< op1: ULEB128 register; op2: SLEB128 offset. */ 396 397 #define DW_CFA_restore UINT8_C(0xc0) /**< low 6 bits: register. */ 397 #define DW_CFA_restore_extended UINT8_C(0x06) /**< op1: ULEB128 register ; op2: ULEB128 offset. */398 #define DW_CFA_restore_extended UINT8_C(0x06) /**< op1: ULEB128 register. */ 398 399 #define DW_CFA_undefined UINT8_C(0x07) /**< op1: ULEB128 register. */ 399 400 #define DW_CFA_same_value UINT8_C(0x08) /**< op1: ULEB128 register. */ … … 421 422 #define DW_CFA_GNU_negative_offset_extended UINT8_C(0x2f) /**< op1: ??; op2: ?? */ 422 423 #define DW_CFA_hi_user UINT8_C(0x3f) /**< User defined operands. */ 424 /** @} */ 425 426 427 /** @name DWREG_X86_XXX - 386+ register number mappings. 428 * @{ */ 429 #define DWREG_X86_EAX 0 430 #define DWREG_X86_ECX 1 431 #define DWREG_X86_EDX 2 432 #define DWREG_X86_EBX 3 433 #define DWREG_X86_ESP 4 434 #define DWREG_X86_EBP 5 435 #define DWREG_X86_ESI 6 436 #define DWREG_X86_EDI 7 437 #define DWREG_X86_RA 8 /* return address (=EIP) */ 438 #define DWREG_X86_EFLAGS 9 439 #define DWREG_X86_ST1 11 440 #define DWREG_X86_ST2 12 441 #define DWREG_X86_ST3 13 442 #define DWREG_X86_ST4 14 443 #define DWREG_X86_ST5 15 444 #define DWREG_X86_ST6 16 445 #define DWREG_X86_ST7 17 446 #define DWREG_X86_XMM0 21 447 #define DWREG_X86_XMM1 22 448 #define DWREG_X86_XMM2 23 449 #define DWREG_X86_XMM3 24 450 #define DWREG_X86_XMM4 25 451 #define DWREG_X86_XMM5 26 452 #define DWREG_X86_XMM6 27 453 #define DWREG_X86_XMM7 28 454 #define DWREG_X86_MM0 29 455 #define DWREG_X86_MM1 30 456 #define DWREG_X86_MM2 31 457 #define DWREG_X86_MM3 32 458 #define DWREG_X86_MM4 33 459 #define DWREG_X86_MM5 34 460 #define DWREG_X86_MM6 35 461 #define DWREG_X86_MM7 36 462 #define DWREG_X86_MXCSR 39 463 #define DWREG_X86_ES 40 464 #define DWREG_X86_CS 41 465 #define DWREG_X86_SS 42 466 #define DWREG_X86_DS 43 467 #define DWREG_X86_FS 44 468 #define DWREG_X86_GS 45 469 #define DWREG_X86_TR 48 470 #define DWREG_X86_LDTR 49 471 /** @} */ 472 473 474 /** @name DWREG_AMD64_XXX - AMD64 register number mappings. 475 * @note This for some braindead reason the first 8 GPR are in intel encoding 476 * order, unlike the DWREG_X86_XXX variant. Utter stupidity. 477 * @{ */ 478 #define DWREG_AMD64_RAX 0 479 #define DWREG_AMD64_RDX 1 480 #define DWREG_AMD64_RCX 2 481 #define DWREG_AMD64_RBX 3 482 #define DWREG_AMD64_RSI 4 483 #define DWREG_AMD64_RDI 5 484 #define DWREG_AMD64_RBP 6 485 #define DWREG_AMD64_RSP 7 486 #define DWREG_AMD64_R8 8 487 #define DWREG_AMD64_R9 9 488 #define DWREG_AMD64_R10 10 489 #define DWREG_AMD64_R11 11 490 #define DWREG_AMD64_R12 12 491 #define DWREG_AMD64_R13 13 492 #define DWREG_AMD64_R14 14 493 #define DWREG_AMD64_R15 15 494 #define DWREG_AMD64_RA 16 /* return address (=RIP) */ 495 #define DWREG_AMD64_XMM0 17 496 #define DWREG_AMD64_XMM1 18 497 #define DWREG_AMD64_XMM2 19 498 #define DWREG_AMD64_XMM3 20 499 #define DWREG_AMD64_XMM4 21 500 #define DWREG_AMD64_XMM5 22 501 #define DWREG_AMD64_XMM6 23 502 #define DWREG_AMD64_XMM7 24 503 #define DWREG_AMD64_XMM8 25 504 #define DWREG_AMD64_XMM9 26 505 #define DWREG_AMD64_XMM10 27 506 #define DWREG_AMD64_XMM11 28 507 #define DWREG_AMD64_XMM12 29 508 #define DWREG_AMD64_XMM13 30 509 #define DWREG_AMD64_XMM14 31 510 #define DWREG_AMD64_XMM15 32 511 #define DWREG_AMD64_ST0 33 512 #define DWREG_AMD64_ST1 34 513 #define DWREG_AMD64_ST2 35 514 #define DWREG_AMD64_ST3 36 515 #define DWREG_AMD64_ST4 37 516 #define DWREG_AMD64_ST5 38 517 #define DWREG_AMD64_ST6 39 518 #define DWREG_AMD64_ST7 40 519 #define DWREG_AMD64_MM0 41 520 #define DWREG_AMD64_MM1 42 521 #define DWREG_AMD64_MM2 43 522 #define DWREG_AMD64_MM3 44 523 #define DWREG_AMD64_MM4 45 524 #define DWREG_AMD64_MM5 46 525 #define DWREG_AMD64_MM6 47 526 #define DWREG_AMD64_MM7 48 527 #define DWREG_AMD64_RFLAGS 49 528 #define DWREG_AMD64_ES 50 529 #define DWREG_AMD64_CS 51 530 #define DWREG_AMD64_SS 52 531 #define DWREG_AMD64_DS 53 532 #define DWREG_AMD64_FS 54 533 #define DWREG_AMD64_GS 55 534 #define DWREG_AMD64_FS_BASE 58 535 #define DWREG_AMD64_GS_BASE 59 536 #define DWREG_AMD64_TR 62 537 #define DWREG_AMD64_LDTR 63 538 #define DWREG_AMD64_MXCSR 64 539 #define DWREG_AMD64_FCW 65 540 #define DWREG_AMD64_FSW 66 423 541 /** @} */ 424 542 … … 1320 1438 1321 1439 /* The link address is 0 for all segments in a relocatable ELF image. */ 1322 RTLDRADDR cb = RT_MAX(pSeg->cb, pSeg->cbMapped); 1440 RTLDRADDR cb = pSeg->cb; 1441 if ( cb < pSeg->cbMapped 1442 && RTLdrGetFormat(hLdrMod) != RTLDRFMT_LX /* for debugging our drivers; 64KB section align by linker, 4KB by loader. */ 1443 ) 1444 cb = pSeg->cbMapped; 1323 1445 return RTDbgModSegmentAdd(pThis->hCnt, pSeg->RVA, cb, pSeg->pszName, 0 /*fFlags*/, NULL); 1324 1446 } … … 1326 1448 1327 1449 /** 1328 * Calls pfnSegmentAdd for each segment in the executable image. 1450 * Calls rtDbgModDwarfAddSegmentsCallback for each segment in the executable 1451 * image. 1329 1452 * 1330 1453 * @returns IPRT status code. … … 1590 1713 if (pThis->fUseLinkAddress) 1591 1714 return pThis->pImgMod->pImgVt->pfnLinkAddressToSegOffset(pThis->pImgMod, LinkAddress, piSeg, poffSeg); 1715 1716 /* If we have a non-zero segment number, assume it's correct for now. 1717 This helps loading watcom linked LX drivers. */ 1718 if (uSegment > 0) 1719 { 1720 *piSeg = uSegment - 1; 1721 *poffSeg = LinkAddress; 1722 return VINF_SUCCESS; 1723 } 1724 1592 1725 return pThis->pImgMod->pImgVt->pfnRvaToSegOffset(pThis->pImgMod, LinkAddress, piSeg, poffSeg); 1593 1726 } … … 2215 2348 * @param pCursor The cursor. 2216 2349 */ 2217 static uint64_t rtDwarfCursor_GetInit alLength(PRTDWARFCURSOR pCursor)2350 static uint64_t rtDwarfCursor_GetInitialLength(PRTDWARFCURSOR pCursor) 2218 2351 { 2219 2352 /* … … 2526 2659 /** The segment size (v4). */ 2527 2660 uint8_t cbSegment; 2661 /** The return register column. UINT8_MAX if default register. */ 2662 uint8_t bRetReg; 2528 2663 /** The LSDA pointer encoding. */ 2529 2664 uint8_t bLsdaPtrEnc; … … 2565 2700 typedef RTDWARFCIEINFO const *PCRTDWARFCIEINFO; 2566 2701 2567 #if 0 2568 2569 typedef struct RTDWARFCFEXPR 2570 { 2571 2572 }; 2573 2574 /** 2575 * Call frame engine state.2576 */ 2577 typedef struct RTDWARFCF STATE2702 2703 /** Number of registers we care about. 2704 * @note We're currently not expecting to be decoding ppc, arm, ia64 or such, 2705 * only x86 and x86_64. We can easily increase the column count. */ 2706 #define RTDWARFCF_MAX_REGISTERS 96 2707 2708 2709 /** 2710 * Call frame state row. 2711 */ 2712 typedef struct RTDWARFCFROW 2578 2713 { 2579 2714 /** Stack worked by DW_CFA_remember_state and DW_CFA_restore_state. */ 2580 struct RTDWARFCFSTATE *pNextOnStack; 2581 2582 2583 2584 } RTDWARFCFSTATE; 2585 #endif 2715 struct RTDWARFCFROW *pNextOnStack; 2716 2717 /** @name CFA - Canonical frame address expression. 2718 * Since there are partial CFA instructions, we cannot be lazy like with the 2719 * register but keep register+offset around. For DW_CFA_def_cfa_expression 2720 * we just take down the program location, though. 2721 * @{ */ 2722 /** Pointer to DW_CFA_def_cfa_expression instruction, NULL if reg+offset. */ 2723 uint8_t const *pbCfaExprInstr; 2724 /** The CFA register offset. */ 2725 int64_t offCfaReg; 2726 /** The CFA base register number. */ 2727 uint16_t uCfaBaseReg; 2728 /** Set if we've got a valid CFA definition. */ 2729 bool fCfaDefined : 1; 2730 /** @} */ 2731 2732 /** Set if on the heap and needs freeing. */ 2733 bool fOnHeap : 1; 2734 /** Pointer to the instructions bytes defining registers. 2735 * NULL means */ 2736 uint8_t const *apbRegInstrs[RTDWARFCF_MAX_REGISTERS]; 2737 } RTDWARFCFROW; 2738 typedef RTDWARFCFROW *PRTDWARFCFROW; 2739 typedef RTDWARFCFROW const *PCRTDWARFCFROW; 2740 2741 /** Row program execution state. */ 2742 typedef struct RTDWARFCFEXEC 2743 { 2744 PRTDWARFCFROW pRow; 2745 /** Number of PC bytes left to advance before we get a hit. */ 2746 uint64_t cbLeftToAdvance; 2747 /** Number of pushed rows. */ 2748 uint32_t cPushes; 2749 /** Set if little endian, clear if big endian. */ 2750 bool fLittleEndian; 2751 /** The CIE. */ 2752 PCRTDWARFCIEINFO pCie; 2753 /** The program counter value for the FDE. Subjected to segment. 2754 * Needed for DW_CFA_set_loc. */ 2755 uint64_t uPcBegin; 2756 /** The offset relative to uPcBegin for which we're searching for a row. 2757 * Needed for DW_CFA_set_loc. */ 2758 uint64_t offInRange; 2759 } RTDWARFCFEXEC; 2760 typedef RTDWARFCFEXEC *PRTDWARFCFEXEC; 2761 2762 2763 /* Set of macros for getting and skipping operands. */ 2764 #define SKIP_ULEB128_OR_LEB128() \ 2765 do \ 2766 { \ 2767 AssertReturn(offInstr < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); \ 2768 } while (pbInstr[offInstr++] & 0x80) 2769 2770 #define GET_ULEB128_AS_U14(a_uDst) \ 2771 do \ 2772 { \ 2773 AssertReturn(offInstr < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); \ 2774 uint8_t b = pbInstr[offInstr++]; \ 2775 (a_uDst) = b & 0x7f; \ 2776 if (b & 0x80) \ 2777 { \ 2778 AssertReturn(offInstr < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); \ 2779 b = pbInstr[offInstr++]; \ 2780 AssertReturn(!(b & 0x80), VERR_DBG_MALFORMED_UNWIND_INFO); \ 2781 (a_uDst) |= (uint16_t)b << 7; \ 2782 } \ 2783 } while (0) 2784 #define GET_ULEB128_AS_U63(a_uDst) \ 2785 do \ 2786 { \ 2787 AssertReturn(offInstr < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); \ 2788 uint8_t b = pbInstr[offInstr++]; \ 2789 (a_uDst) = b & 0x7f; \ 2790 if (b & 0x80) \ 2791 { \ 2792 unsigned cShift = 7; \ 2793 do \ 2794 { \ 2795 AssertReturn(offInstr < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); \ 2796 AssertReturn(cShift < 63, VERR_DWARF_LEB_OVERFLOW); \ 2797 b = pbInstr[offInstr++]; \ 2798 (a_uDst) |= (uint16_t)(b & 0x7f) << cShift; \ 2799 cShift += 7; \ 2800 } while (b & 0x80); \ 2801 } \ 2802 } while (0) 2803 #define GET_LEB128_AS_I63(a_uDst) \ 2804 do \ 2805 { \ 2806 AssertReturn(offInstr < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); \ 2807 uint8_t b = pbInstr[offInstr++]; \ 2808 if (!(b & 0x80)) \ 2809 (a_uDst) = !(b & 0x40) ? b : (int64_t)(int8_t)(b | 0x80); \ 2810 else \ 2811 { \ 2812 /* Read value into unsigned variable: */ \ 2813 unsigned cShift = 7; \ 2814 uint64_t uTmp = b & 0x7f; \ 2815 do \ 2816 { \ 2817 AssertReturn(offInstr < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); \ 2818 AssertReturn(cShift < 63, VERR_DWARF_LEB_OVERFLOW); \ 2819 b = pbInstr[offInstr++]; \ 2820 uTmp |= (uint16_t)(b & 0x7f) << cShift; \ 2821 cShift += 7; \ 2822 } while (b & 0x80); \ 2823 /* Sign extend before setting the destination value: */ \ 2824 cShift -= 7 + 1; \ 2825 if (uTmp & RT_BIT_64(cShift)) \ 2826 uTmp |= ~(RT_BIT_64(cShift) - 1); \ 2827 (a_uDst) = (int64_t)uTmp; \ 2828 } \ 2829 } while (0) 2830 2831 #define SKIP_BLOCK() \ 2832 do \ 2833 { \ 2834 uint16_t cbBlock; \ 2835 GET_ULEB128_AS_U14(cbBlock); \ 2836 AssertReturn(offInstr + cbBlock <= cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); \ 2837 offInstr += cbBlock; \ 2838 } while (0) 2839 2840 2841 static int rtDwarfUnwind_Execute(PRTDWARFCFEXEC pExecState, uint8_t const *pbInstr, uint32_t cbInstr) 2842 { 2843 PRTDWARFCFROW pRow = pExecState->pRow; 2844 for (uint32_t offInstr = 0; offInstr < cbInstr;) 2845 { 2846 /* 2847 * Instruction switches. 2848 */ 2849 uint8_t const bInstr = pbInstr[offInstr++]; 2850 switch (bInstr & DW_CFA_high_bit_mask) 2851 { 2852 case DW_CFA_advance_loc: 2853 { 2854 uint8_t const cbAdvance = bInstr & ~DW_CFA_high_bit_mask; 2855 if (cbAdvance > pExecState->cbLeftToAdvance) 2856 return VINF_SUCCESS; 2857 pExecState->cbLeftToAdvance -= cbAdvance; 2858 break; 2859 } 2860 2861 case DW_CFA_offset: 2862 { 2863 uint8_t iReg = bInstr & ~DW_CFA_high_bit_mask; 2864 if (iReg < RT_ELEMENTS(pRow->apbRegInstrs)) 2865 pRow->apbRegInstrs[iReg] = &pbInstr[offInstr - 1]; 2866 SKIP_ULEB128_OR_LEB128(); 2867 break; 2868 } 2869 2870 case 0: 2871 switch (bInstr) 2872 { 2873 case DW_CFA_nop: 2874 break; 2875 2876 /* 2877 * Register instructions. 2878 */ 2879 case DW_CFA_register: 2880 case DW_CFA_offset_extended: 2881 case DW_CFA_offset_extended_sf: 2882 case DW_CFA_val_offset: 2883 case DW_CFA_val_offset_sf: 2884 { 2885 uint8_t const * const pbCurInstr = &pbInstr[offInstr - 1]; 2886 uint16_t iReg; 2887 GET_ULEB128_AS_U14(iReg); 2888 if (iReg < RT_ELEMENTS(pRow->apbRegInstrs)) 2889 pRow->apbRegInstrs[iReg] = pbCurInstr; 2890 SKIP_ULEB128_OR_LEB128(); 2891 break; 2892 } 2893 2894 case DW_CFA_expression: 2895 case DW_CFA_val_expression: 2896 { 2897 uint8_t const * const pbCurInstr = &pbInstr[offInstr - 1]; 2898 uint16_t iReg; 2899 GET_ULEB128_AS_U14(iReg); 2900 if (iReg < RT_ELEMENTS(pRow->apbRegInstrs)) 2901 pRow->apbRegInstrs[iReg] = pbCurInstr; 2902 SKIP_BLOCK(); 2903 break; 2904 } 2905 2906 case DW_CFA_restore_extended: 2907 { 2908 uint8_t const * const pbCurInstr = &pbInstr[offInstr - 1]; 2909 uint16_t iReg; 2910 GET_ULEB128_AS_U14(iReg); 2911 if (iReg < RT_ELEMENTS(pRow->apbRegInstrs)) 2912 pRow->apbRegInstrs[iReg] = pbCurInstr; 2913 break; 2914 } 2915 2916 case DW_CFA_undefined: 2917 { 2918 uint16_t iReg; 2919 GET_ULEB128_AS_U14(iReg); 2920 if (iReg < RT_ELEMENTS(pRow->apbRegInstrs)) 2921 pRow->apbRegInstrs[iReg] = NULL; 2922 break; 2923 } 2924 2925 case DW_CFA_same_value: 2926 { 2927 uint8_t const * const pbCurInstr = &pbInstr[offInstr - 1]; 2928 uint16_t iReg; 2929 GET_ULEB128_AS_U14(iReg); 2930 if (iReg < RT_ELEMENTS(pRow->apbRegInstrs)) 2931 pRow->apbRegInstrs[iReg] = pbCurInstr; 2932 break; 2933 } 2934 2935 2936 /* 2937 * CFA instructions. 2938 */ 2939 case DW_CFA_def_cfa: 2940 { 2941 GET_ULEB128_AS_U14(pRow->uCfaBaseReg); 2942 uint64_t offCfaReg; 2943 GET_ULEB128_AS_U63(offCfaReg); 2944 pRow->offCfaReg = offCfaReg; 2945 pRow->pbCfaExprInstr = NULL; 2946 pRow->fCfaDefined = true; 2947 break; 2948 } 2949 2950 case DW_CFA_def_cfa_register: 2951 { 2952 GET_ULEB128_AS_U14(pRow->uCfaBaseReg); 2953 pRow->pbCfaExprInstr = NULL; 2954 pRow->fCfaDefined = true; 2955 /* Leaves offCfaReg as is. */ 2956 break; 2957 } 2958 2959 case DW_CFA_def_cfa_offset: 2960 { 2961 uint64_t offCfaReg; 2962 GET_ULEB128_AS_U63(offCfaReg); 2963 pRow->offCfaReg = offCfaReg; 2964 pRow->pbCfaExprInstr = NULL; 2965 pRow->fCfaDefined = true; 2966 /* Leaves uCfaBaseReg as is. */ 2967 break; 2968 } 2969 2970 case DW_CFA_def_cfa_sf: 2971 GET_ULEB128_AS_U14(pRow->uCfaBaseReg); 2972 GET_LEB128_AS_I63(pRow->offCfaReg); 2973 pRow->pbCfaExprInstr = NULL; 2974 pRow->fCfaDefined = true; 2975 break; 2976 2977 case DW_CFA_def_cfa_offset_sf: 2978 GET_LEB128_AS_I63(pRow->offCfaReg); 2979 pRow->pbCfaExprInstr = NULL; 2980 pRow->fCfaDefined = true; 2981 /* Leaves uCfaBaseReg as is. */ 2982 break; 2983 2984 case DW_CFA_def_cfa_expression: 2985 pRow->pbCfaExprInstr = &pbInstr[offInstr - 1]; 2986 pRow->fCfaDefined = true; 2987 SKIP_BLOCK(); 2988 break; 2989 2990 /* 2991 * Less likely instructions: 2992 */ 2993 case DW_CFA_advance_loc1: 2994 { 2995 AssertReturn(offInstr < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); 2996 uint8_t const cbAdvance = pbInstr[offInstr++]; 2997 if (cbAdvance > pExecState->cbLeftToAdvance) 2998 return VINF_SUCCESS; 2999 pExecState->cbLeftToAdvance -= cbAdvance; 3000 break; 3001 } 3002 3003 case DW_CFA_advance_loc2: 3004 { 3005 AssertReturn(offInstr + 1 < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); 3006 uint16_t const cbAdvance = pExecState->fLittleEndian 3007 ? RT_MAKE_U16(pbInstr[offInstr], pbInstr[offInstr + 1]) 3008 : RT_MAKE_U16(pbInstr[offInstr + 1], pbInstr[offInstr]); 3009 if (cbAdvance > pExecState->cbLeftToAdvance) 3010 return VINF_SUCCESS; 3011 pExecState->cbLeftToAdvance -= cbAdvance; 3012 offInstr += 2; 3013 break; 3014 } 3015 3016 case DW_CFA_advance_loc4: 3017 { 3018 AssertReturn(offInstr + 3 < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); 3019 uint32_t const cbAdvance = pExecState->fLittleEndian 3020 ? RT_MAKE_U32_FROM_U8(pbInstr[offInstr + 0], pbInstr[offInstr + 1], 3021 pbInstr[offInstr + 2], pbInstr[offInstr + 3]) 3022 : RT_MAKE_U32_FROM_U8(pbInstr[offInstr + 3], pbInstr[offInstr + 2], 3023 pbInstr[offInstr + 1], pbInstr[offInstr + 0]); 3024 if (cbAdvance > pExecState->cbLeftToAdvance) 3025 return VINF_SUCCESS; 3026 pExecState->cbLeftToAdvance -= cbAdvance; 3027 offInstr += 4; 3028 break; 3029 } 3030 3031 /* 3032 * This bugger is really annoying and probably never used. 3033 */ 3034 case DW_CFA_set_loc: 3035 { 3036 /* Ignore the segment number. */ 3037 if (pExecState->pCie->cbSegment) 3038 { 3039 offInstr += pExecState->pCie->cbSegment; 3040 AssertReturn(offInstr < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); 3041 } 3042 3043 /* Retrieve the address. sigh. */ 3044 uint64_t uAddress; 3045 switch (pExecState->pCie->bAddressPtrEnc & (DW_EH_PE_FORMAT_MASK | DW_EH_PE_indirect)) 3046 { 3047 case DW_EH_PE_udata2: 3048 AssertReturn(offInstr + 1 < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); 3049 if (pExecState->fLittleEndian) 3050 uAddress = RT_MAKE_U16(pbInstr[offInstr], pbInstr[offInstr + 1]); 3051 else 3052 uAddress = RT_MAKE_U16(pbInstr[offInstr + 1], pbInstr[offInstr]); 3053 offInstr += 2; 3054 break; 3055 case DW_EH_PE_sdata2: 3056 AssertReturn(offInstr + 1 < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); 3057 if (pExecState->fLittleEndian) 3058 uAddress = (int64_t)(int16_t)RT_MAKE_U16(pbInstr[offInstr], pbInstr[offInstr + 1]); 3059 else 3060 uAddress = (int64_t)(int16_t)RT_MAKE_U16(pbInstr[offInstr + 1], pbInstr[offInstr]); 3061 offInstr += 2; 3062 break; 3063 case DW_EH_PE_udata4: 3064 AssertReturn(offInstr + 3 < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); 3065 if (pExecState->fLittleEndian) 3066 uAddress = RT_MAKE_U32_FROM_U8(pbInstr[offInstr + 0], pbInstr[offInstr + 1], 3067 pbInstr[offInstr + 2], pbInstr[offInstr + 3]); 3068 else 3069 uAddress = RT_MAKE_U32_FROM_U8(pbInstr[offInstr + 3], pbInstr[offInstr + 2], 3070 pbInstr[offInstr + 1], pbInstr[offInstr + 0]); 3071 3072 offInstr += 4; 3073 break; 3074 case DW_EH_PE_sdata4: 3075 AssertReturn(offInstr + 3 < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); 3076 if (pExecState->fLittleEndian) 3077 uAddress = (int64_t)(int32_t)RT_MAKE_U32_FROM_U8(pbInstr[offInstr + 0], pbInstr[offInstr + 1], 3078 pbInstr[offInstr + 2], pbInstr[offInstr + 3]); 3079 else 3080 uAddress = (int64_t)(int32_t)RT_MAKE_U32_FROM_U8(pbInstr[offInstr + 3], pbInstr[offInstr + 2], 3081 pbInstr[offInstr + 1], pbInstr[offInstr + 0]); 3082 offInstr += 4; 3083 break; 3084 case DW_EH_PE_udata8: 3085 case DW_EH_PE_sdata8: 3086 AssertReturn(offInstr + 7 < cbInstr, VERR_DBG_MALFORMED_UNWIND_INFO); 3087 if (pExecState->fLittleEndian) 3088 uAddress = RT_MAKE_U64_FROM_U8(pbInstr[offInstr + 0], pbInstr[offInstr + 1], 3089 pbInstr[offInstr + 2], pbInstr[offInstr + 3], 3090 pbInstr[offInstr + 4], pbInstr[offInstr + 5], 3091 pbInstr[offInstr + 6], pbInstr[offInstr + 7]); 3092 else 3093 uAddress = RT_MAKE_U64_FROM_U8(pbInstr[offInstr + 7], pbInstr[offInstr + 6], 3094 pbInstr[offInstr + 5], pbInstr[offInstr + 4], 3095 pbInstr[offInstr + 3], pbInstr[offInstr + 2], 3096 pbInstr[offInstr + 1], pbInstr[offInstr + 0]); 3097 offInstr += 8; 3098 break; 3099 case DW_EH_PE_sleb128: 3100 case DW_EH_PE_uleb128: 3101 default: 3102 AssertMsgFailedReturn(("%#x\n", pExecState->pCie->bAddressPtrEnc), VERR_DWARF_TODO); 3103 } 3104 AssertReturn(uAddress >= pExecState->uPcBegin, VERR_DBG_MALFORMED_UNWIND_INFO); 3105 3106 /* Did we advance past the desire address already? */ 3107 if (uAddress > pExecState->uPcBegin + pExecState->offInRange) 3108 return VINF_SUCCESS; 3109 pExecState->cbLeftToAdvance = pExecState->uPcBegin + pExecState->offInRange - uAddress; 3110 break; 3111 3112 3113 /* 3114 * Row state push/pop instructions. 3115 */ 3116 3117 case DW_CFA_remember_state: 3118 { 3119 AssertReturn(pExecState->cPushes < 10, VERR_DBG_MALFORMED_UNWIND_INFO); 3120 PRTDWARFCFROW pNewRow = (PRTDWARFCFROW)RTMemTmpAlloc(sizeof(*pNewRow)); 3121 AssertReturn(pNewRow, VERR_NO_TMP_MEMORY); 3122 memcpy(pNewRow, pRow, sizeof(*pNewRow)); 3123 pNewRow->pNextOnStack = pRow; 3124 pNewRow->fOnHeap = true; 3125 pExecState->pRow = pNewRow; 3126 pExecState->cPushes += 1; 3127 pRow = pNewRow; 3128 break; 3129 } 3130 3131 case DW_CFA_restore_state: 3132 AssertReturn(pRow->pNextOnStack, VERR_DBG_MALFORMED_UNWIND_INFO); 3133 Assert(pRow->fOnHeap); 3134 Assert(pExecState->cPushes > 0); 3135 pExecState->cPushes -= 1; 3136 pExecState->pRow = pRow->pNextOnStack; 3137 RTMemTmpFree(pRow); 3138 pRow = pExecState->pRow; 3139 break; 3140 } 3141 } 3142 break; 3143 3144 case DW_CFA_restore: 3145 { 3146 uint8_t const * const pbCurInstr = &pbInstr[offInstr - 1]; 3147 uint8_t const iReg = bInstr & ~DW_CFA_high_bit_mask; 3148 if (iReg < RT_ELEMENTS(pRow->apbRegInstrs)) 3149 pRow->apbRegInstrs[iReg] = pbCurInstr; 3150 break; 3151 } 3152 } 3153 } 3154 return VINF_TRY_AGAIN; 3155 } 3156 3157 3158 /** 3159 * Register getter for AMD64. 3160 * 3161 * @returns true if found, false if not. 3162 * @param pState The unwind state to get the register from. 3163 * @param iReg The dwarf register number. 3164 * @param puValue Where to store the register value. 3165 */ 3166 static bool rtDwarfUnwind_Amd64GetRegFromState(PCRTDBGUNWINDSTATE pState, uint16_t iReg, uint64_t *puValue) 3167 { 3168 switch (iReg) 3169 { 3170 case DWREG_AMD64_RAX: *puValue = pState->u.x86.auRegs[X86_GREG_xAX]; return true; 3171 case DWREG_AMD64_RDX: *puValue = pState->u.x86.auRegs[X86_GREG_xDX]; return true; 3172 case DWREG_AMD64_RCX: *puValue = pState->u.x86.auRegs[X86_GREG_xCX]; return true; 3173 case DWREG_AMD64_RBX: *puValue = pState->u.x86.auRegs[X86_GREG_xBX]; return true; 3174 case DWREG_AMD64_RSI: *puValue = pState->u.x86.auRegs[X86_GREG_xSI]; return true; 3175 case DWREG_AMD64_RDI: *puValue = pState->u.x86.auRegs[X86_GREG_xDI]; return true; 3176 case DWREG_AMD64_RBP: *puValue = pState->u.x86.auRegs[X86_GREG_xBP]; return true; 3177 case DWREG_AMD64_RSP: *puValue = pState->u.x86.auRegs[X86_GREG_xSP]; return true; 3178 case DWREG_AMD64_R8: *puValue = pState->u.x86.auRegs[X86_GREG_x8]; return true; 3179 case DWREG_AMD64_R9: *puValue = pState->u.x86.auRegs[X86_GREG_x9]; return true; 3180 case DWREG_AMD64_R10: *puValue = pState->u.x86.auRegs[X86_GREG_x10]; return true; 3181 case DWREG_AMD64_R11: *puValue = pState->u.x86.auRegs[X86_GREG_x11]; return true; 3182 case DWREG_AMD64_R12: *puValue = pState->u.x86.auRegs[X86_GREG_x12]; return true; 3183 case DWREG_AMD64_R13: *puValue = pState->u.x86.auRegs[X86_GREG_x13]; return true; 3184 case DWREG_AMD64_R14: *puValue = pState->u.x86.auRegs[X86_GREG_x14]; return true; 3185 case DWREG_AMD64_R15: *puValue = pState->u.x86.auRegs[X86_GREG_x15]; return true; 3186 case DWREG_AMD64_RFLAGS: *puValue = pState->u.x86.uRFlags; return true; 3187 case DWREG_AMD64_ES: *puValue = pState->u.x86.auSegs[X86_SREG_ES]; return true; 3188 case DWREG_AMD64_CS: *puValue = pState->u.x86.auSegs[X86_SREG_CS]; return true; 3189 case DWREG_AMD64_SS: *puValue = pState->u.x86.auSegs[X86_SREG_SS]; return true; 3190 case DWREG_AMD64_DS: *puValue = pState->u.x86.auSegs[X86_SREG_DS]; return true; 3191 case DWREG_AMD64_FS: *puValue = pState->u.x86.auSegs[X86_SREG_FS]; return true; 3192 case DWREG_AMD64_GS: *puValue = pState->u.x86.auSegs[X86_SREG_GS]; return true; 3193 } 3194 return false; 3195 } 3196 3197 3198 /** 3199 * Register getter for 386+. 3200 * 3201 * @returns true if found, false if not. 3202 * @param pState The unwind state to get the register from. 3203 * @param iReg The dwarf register number. 3204 * @param puValue Where to store the register value. 3205 */ 3206 static bool rtDwarfUnwind_X86GetRegFromState(PCRTDBGUNWINDSTATE pState, uint16_t iReg, uint64_t *puValue) 3207 { 3208 switch (iReg) 3209 { 3210 case DWREG_X86_EAX: *puValue = pState->u.x86.auRegs[X86_GREG_xAX]; return true; 3211 case DWREG_X86_ECX: *puValue = pState->u.x86.auRegs[X86_GREG_xCX]; return true; 3212 case DWREG_X86_EDX: *puValue = pState->u.x86.auRegs[X86_GREG_xDX]; return true; 3213 case DWREG_X86_EBX: *puValue = pState->u.x86.auRegs[X86_GREG_xBX]; return true; 3214 case DWREG_X86_ESP: *puValue = pState->u.x86.auRegs[X86_GREG_xSP]; return true; 3215 case DWREG_X86_EBP: *puValue = pState->u.x86.auRegs[X86_GREG_xBP]; return true; 3216 case DWREG_X86_ESI: *puValue = pState->u.x86.auRegs[X86_GREG_xSI]; return true; 3217 case DWREG_X86_EDI: *puValue = pState->u.x86.auRegs[X86_GREG_xDI]; return true; 3218 case DWREG_X86_EFLAGS: *puValue = pState->u.x86.uRFlags; return true; 3219 case DWREG_X86_ES: *puValue = pState->u.x86.auSegs[X86_SREG_ES]; return true; 3220 case DWREG_X86_CS: *puValue = pState->u.x86.auSegs[X86_SREG_CS]; return true; 3221 case DWREG_X86_SS: *puValue = pState->u.x86.auSegs[X86_SREG_SS]; return true; 3222 case DWREG_X86_DS: *puValue = pState->u.x86.auSegs[X86_SREG_DS]; return true; 3223 case DWREG_X86_FS: *puValue = pState->u.x86.auSegs[X86_SREG_FS]; return true; 3224 case DWREG_X86_GS: *puValue = pState->u.x86.auSegs[X86_SREG_GS]; return true; 3225 } 3226 return false; 3227 } 3228 3229 /** Register getter. */ 3230 typedef bool FNDWARFUNWINDGEREGFROMSTATE(PCRTDBGUNWINDSTATE pState, uint16_t iReg, uint64_t *puValue); 3231 /** Pointer to a register getter. */ 3232 typedef FNDWARFUNWINDGEREGFROMSTATE *PFNDWARFUNWINDGEREGFROMSTATE; 3233 3234 3235 3236 /** 3237 * Does the heavy work for figuring out the return value of a register. 3238 * 3239 * @returns IPRT status code. 3240 * @retval VERR_NOT_FOUND if register is undefined. 3241 * 3242 * @param pRow The DWARF unwind table "row" to use. 3243 * @param uReg The DWARF register number. 3244 * @param pCie The corresponding CIE. 3245 * @param uCfa The canonical frame address to use. 3246 * @param pState The unwind to use when reading stack. 3247 * @param pOldState The unwind state to get register values from. 3248 * @param pfnGetReg The register value getter. 3249 * @param puValue Where to store the return value. 3250 * @param cbValue The size this register would have on the stack. 3251 */ 3252 static int rtDwarfUnwind_CalcRegisterValue(PRTDWARFCFROW pRow, unsigned uReg, PCRTDWARFCIEINFO pCie, uint64_t uCfa, 3253 PRTDBGUNWINDSTATE pState, PCRTDBGUNWINDSTATE pOldState, 3254 PFNDWARFUNWINDGEREGFROMSTATE pfnGetReg, uint64_t *puValue, uint8_t cbValue) 3255 { 3256 Assert(uReg < RT_ELEMENTS(pRow->apbRegInstrs)); 3257 uint8_t const *pbInstr = pRow->apbRegInstrs[uReg]; 3258 if (!pbInstr) 3259 return VERR_NOT_FOUND; 3260 3261 uint32_t cbInstr = UINT32_MAX / 2; 3262 uint32_t offInstr = 1; 3263 uint8_t const bInstr = *pbInstr; 3264 switch (bInstr) 3265 { 3266 default: 3267 if ((bInstr & DW_CFA_high_bit_mask) == DW_CFA_offset) 3268 { 3269 uint64_t offCfa; 3270 GET_ULEB128_AS_U63(offCfa); 3271 int rc = pState->pfnReadStack(pState, uCfa + (int64_t)offCfa * pCie->iDataAlignFactor, cbValue, puValue); 3272 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_offset %#RX64: %Rrc, %#RX64\n", uReg, uCfa + (int64_t)offCfa * pCie->iDataAlignFactor, rc, *puValue)); 3273 return rc; 3274 } 3275 AssertReturn((bInstr & DW_CFA_high_bit_mask) == DW_CFA_restore, VERR_INTERNAL_ERROR); 3276 RT_FALL_THRU(); 3277 case DW_CFA_restore_extended: 3278 /* Need to search the CIE for the rule. */ 3279 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_restore/extended:\n", uReg)); 3280 AssertFailedReturn(VERR_DWARF_TODO); 3281 3282 case DW_CFA_offset_extended: 3283 { 3284 SKIP_ULEB128_OR_LEB128(); 3285 uint64_t offCfa; 3286 GET_ULEB128_AS_U63(offCfa); 3287 int rc = pState->pfnReadStack(pState, uCfa + (int64_t)offCfa * pCie->iDataAlignFactor, cbValue, puValue); 3288 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_offset_extended %#RX64: %Rrc, %#RX64\n", uReg, uCfa + (int64_t)offCfa * pCie->iDataAlignFactor, rc, *puValue)); 3289 return rc; 3290 } 3291 3292 case DW_CFA_offset_extended_sf: 3293 { 3294 SKIP_ULEB128_OR_LEB128(); 3295 int64_t offCfa; 3296 GET_LEB128_AS_I63(offCfa); 3297 int rc = pState->pfnReadStack(pState, uCfa + offCfa * pCie->iDataAlignFactor, cbValue, puValue); 3298 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_offset_extended_sf %#RX64: %Rrc, %#RX64\n", uReg, uCfa + offCfa * pCie->iDataAlignFactor, rc, *puValue)); 3299 return rc; 3300 } 3301 3302 case DW_CFA_val_offset: 3303 { 3304 SKIP_ULEB128_OR_LEB128(); 3305 uint64_t offCfa; 3306 GET_ULEB128_AS_U63(offCfa); 3307 *puValue = uCfa + (int64_t)offCfa * pCie->iDataAlignFactor; 3308 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_val_offset: %#RX64\n", uReg, *puValue)); 3309 return VINF_SUCCESS; 3310 } 3311 3312 case DW_CFA_val_offset_sf: 3313 { 3314 SKIP_ULEB128_OR_LEB128(); 3315 int64_t offCfa; 3316 GET_LEB128_AS_I63(offCfa); 3317 *puValue = uCfa + offCfa * pCie->iDataAlignFactor; 3318 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_val_offset_sf: %#RX64\n", uReg, *puValue)); 3319 return VINF_SUCCESS; 3320 } 3321 3322 case DW_CFA_register: 3323 { 3324 SKIP_ULEB128_OR_LEB128(); 3325 uint16_t iSrcReg; 3326 GET_ULEB128_AS_U14(iSrcReg); 3327 if (pfnGetReg(pOldState, uReg, puValue)) 3328 { 3329 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_register: %#RX64\n", uReg, *puValue)); 3330 return VINF_SUCCESS; 3331 } 3332 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_register: VERR_NOT_FOUND\n", uReg)); 3333 return VERR_NOT_FOUND; 3334 } 3335 3336 case DW_CFA_expression: 3337 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_expression: TODO\n", uReg)); 3338 AssertFailedReturn(VERR_DWARF_TODO); 3339 3340 case DW_CFA_val_expression: 3341 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_val_expression: TODO\n", uReg)); 3342 AssertFailedReturn(VERR_DWARF_TODO); 3343 3344 case DW_CFA_undefined: 3345 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_undefined\n", uReg)); 3346 return VERR_NOT_FOUND; 3347 3348 case DW_CFA_same_value: 3349 if (pfnGetReg(pOldState, uReg, puValue)) 3350 { 3351 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_same_value: %#RX64\n", uReg, *puValue)); 3352 return VINF_SUCCESS; 3353 } 3354 Log8(("rtDwarfUnwind_CalcRegisterValue(%#x): DW_CFA_same_value: VERR_NOT_FOUND\n", uReg)); 3355 return VERR_NOT_FOUND; 3356 } 3357 } 3358 3359 3360 DECLINLINE(void) rtDwarfUnwind_UpdateX86GRegFromRow(PRTDBGUNWINDSTATE pState, PCRTDBGUNWINDSTATE pOldState, unsigned idxGReg, 3361 PRTDWARFCFROW pRow, unsigned idxDwReg, PCRTDWARFCIEINFO pCie, 3362 uint64_t uCfa, PFNDWARFUNWINDGEREGFROMSTATE pfnGetReg, uint8_t cbGReg) 3363 { 3364 int rc = rtDwarfUnwind_CalcRegisterValue(pRow, idxDwReg, pCie, uCfa, pState, pOldState, pfnGetReg, 3365 &pState->u.x86.auRegs[idxGReg], cbGReg); 3366 if (RT_SUCCESS(rc)) 3367 pState->u.x86.Loaded.s.fRegs |= RT_BIT_32(idxGReg); 3368 } 3369 3370 3371 DECLINLINE(void) rtDwarfUnwind_UpdateX86SRegFromRow(PRTDBGUNWINDSTATE pState, PCRTDBGUNWINDSTATE pOldState, unsigned idxSReg, 3372 PRTDWARFCFROW pRow, unsigned idxDwReg, PCRTDWARFCIEINFO pCie, 3373 uint64_t uCfa, PFNDWARFUNWINDGEREGFROMSTATE pfnGetReg) 3374 { 3375 uint64_t uValue = pState->u.x86.auSegs[idxSReg]; 3376 int rc = rtDwarfUnwind_CalcRegisterValue(pRow, idxDwReg, pCie, uCfa, pState, pOldState, pfnGetReg, &uValue, sizeof(uint16_t)); 3377 if (RT_SUCCESS(rc)) 3378 { 3379 pState->u.x86.auSegs[idxSReg] = (uint16_t)uValue; 3380 pState->u.x86.Loaded.s.fSegs |= RT_BIT_32(idxSReg); 3381 } 3382 } 3383 3384 3385 DECLINLINE(void) rtDwarfUnwind_UpdateX86RFlagsFromRow(PRTDBGUNWINDSTATE pState, PCRTDBGUNWINDSTATE pOldState, 3386 PRTDWARFCFROW pRow, unsigned idxDwReg, PCRTDWARFCIEINFO pCie, 3387 uint64_t uCfa, PFNDWARFUNWINDGEREGFROMSTATE pfnGetReg) 3388 { 3389 int rc = rtDwarfUnwind_CalcRegisterValue(pRow, idxDwReg, pCie, uCfa, pState, pOldState, pfnGetReg, 3390 &pState->u.x86.uRFlags, sizeof(uint32_t)); 3391 if (RT_SUCCESS(rc)) 3392 pState->u.x86.Loaded.s.fRFlags = 1; 3393 } 3394 3395 3396 DECLINLINE(void) rtDwarfUnwind_UpdatePCFromRow(PRTDBGUNWINDSTATE pState, PCRTDBGUNWINDSTATE pOldState, 3397 PRTDWARFCFROW pRow, unsigned idxDwReg, PCRTDWARFCIEINFO pCie, 3398 uint64_t uCfa, PFNDWARFUNWINDGEREGFROMSTATE pfnGetReg, uint8_t cbPc) 3399 { 3400 if (pCie->bRetReg != UINT8_MAX) 3401 idxDwReg = pCie->bRetReg; 3402 int rc = rtDwarfUnwind_CalcRegisterValue(pRow, idxDwReg, pCie, uCfa, pState, pOldState, pfnGetReg, &pState->uPc, cbPc); 3403 if (RT_SUCCESS(rc)) 3404 pState->u.x86.Loaded.s.fPc = 1; 3405 else 3406 { 3407 rc = pState->pfnReadStack(pState, uCfa - cbPc, cbPc, &pState->uPc); 3408 if (RT_SUCCESS(rc)) 3409 pState->u.x86.Loaded.s.fPc = 1; 3410 } 3411 } 3412 3413 3414 3415 /** 3416 * Updates @a pState with the rules found in @a pRow. 3417 * 3418 * @returns IPRT status code. 3419 * @param pState The unwind state to update. 3420 * @param pRow The "row" in the dwarf unwind table. 3421 * @param pCie The CIE structure for the row. 3422 */ 3423 static int rtDwarfUnwind_UpdateStateFromRow(PRTDBGUNWINDSTATE pState, PRTDWARFCFROW pRow, PCRTDWARFCIEINFO pCie) 3424 { 3425 /* 3426 * We need to make a copy of the current state so we can get at the 3427 * current register values while calculating the ones of the next frame. 3428 */ 3429 RTDBGUNWINDSTATE const Old = *pState; 3430 3431 /* 3432 * Get the register state getter. 3433 */ 3434 PFNDWARFUNWINDGEREGFROMSTATE pfnGetReg; 3435 switch (pState->enmArch) 3436 { 3437 case RTLDRARCH_AMD64: 3438 pfnGetReg = rtDwarfUnwind_Amd64GetRegFromState; 3439 break; 3440 case RTLDRARCH_X86_32: 3441 case RTLDRARCH_X86_16: 3442 pfnGetReg = rtDwarfUnwind_X86GetRegFromState; 3443 break; 3444 default: 3445 return VERR_NOT_SUPPORTED; 3446 } 3447 3448 /* 3449 * Calc the canonical frame address for the current row. 3450 */ 3451 AssertReturn(pRow->fCfaDefined, VERR_DBG_MALFORMED_UNWIND_INFO); 3452 uint64_t uCfa = 0; 3453 if (!pRow->pbCfaExprInstr) 3454 { 3455 pfnGetReg(&Old, pRow->uCfaBaseReg, &uCfa); 3456 uCfa += pRow->offCfaReg; 3457 } 3458 else 3459 { 3460 AssertFailed(); 3461 return VERR_DWARF_TODO; 3462 } 3463 Log8(("rtDwarfUnwind_UpdateStateFromRow: uCfa=%RX64\n", uCfa)); 3464 3465 /* 3466 * Do the architecture specific register updating. 3467 */ 3468 switch (pState->enmArch) 3469 { 3470 case RTLDRARCH_AMD64: 3471 pState->u.x86.FrameAddr.off = uCfa - 8*2; 3472 pState->u.x86.Loaded.fAll = 0; 3473 pState->u.x86.Loaded.s.fFrameAddr = 1; 3474 rtDwarfUnwind_UpdatePCFromRow(pState, &Old, pRow, DWREG_AMD64_RA, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3475 rtDwarfUnwind_UpdateX86RFlagsFromRow(pState, &Old, pRow, DWREG_AMD64_RFLAGS, pCie, uCfa, pfnGetReg); 3476 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xAX, pRow, DWREG_AMD64_RAX, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3477 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xCX, pRow, DWREG_AMD64_RCX, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3478 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xDX, pRow, DWREG_AMD64_RDX, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3479 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xBX, pRow, DWREG_AMD64_RBX, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3480 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xSP, pRow, DWREG_AMD64_RSP, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3481 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xBP, pRow, DWREG_AMD64_RBP, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3482 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xSI, pRow, DWREG_AMD64_RSI, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3483 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xDI, pRow, DWREG_AMD64_RDI, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3484 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_x8, pRow, DWREG_AMD64_R8, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3485 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_x9, pRow, DWREG_AMD64_R9, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3486 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_x10, pRow, DWREG_AMD64_R10, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3487 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_x11, pRow, DWREG_AMD64_R11, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3488 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_x12, pRow, DWREG_AMD64_R12, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3489 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_x13, pRow, DWREG_AMD64_R13, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3490 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_x14, pRow, DWREG_AMD64_R14, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3491 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_x15, pRow, DWREG_AMD64_R15, pCie, uCfa, pfnGetReg, sizeof(uint64_t)); 3492 rtDwarfUnwind_UpdateX86SRegFromRow(pState, &Old, X86_SREG_ES, pRow, DWREG_AMD64_ES, pCie, uCfa, pfnGetReg); 3493 rtDwarfUnwind_UpdateX86SRegFromRow(pState, &Old, X86_SREG_CS, pRow, DWREG_AMD64_CS, pCie, uCfa, pfnGetReg); 3494 rtDwarfUnwind_UpdateX86SRegFromRow(pState, &Old, X86_SREG_SS, pRow, DWREG_AMD64_SS, pCie, uCfa, pfnGetReg); 3495 rtDwarfUnwind_UpdateX86SRegFromRow(pState, &Old, X86_SREG_DS, pRow, DWREG_AMD64_DS, pCie, uCfa, pfnGetReg); 3496 rtDwarfUnwind_UpdateX86SRegFromRow(pState, &Old, X86_SREG_FS, pRow, DWREG_AMD64_FS, pCie, uCfa, pfnGetReg); 3497 rtDwarfUnwind_UpdateX86SRegFromRow(pState, &Old, X86_SREG_GS, pRow, DWREG_AMD64_GS, pCie, uCfa, pfnGetReg); 3498 break; 3499 3500 case RTLDRARCH_X86_32: 3501 case RTLDRARCH_X86_16: 3502 pState->u.x86.FrameAddr.off = uCfa - 4*2; 3503 pState->u.x86.Loaded.fAll = 0; 3504 pState->u.x86.Loaded.s.fFrameAddr = 1; 3505 rtDwarfUnwind_UpdatePCFromRow(pState, &Old, pRow, DWREG_X86_RA, pCie, uCfa, pfnGetReg, sizeof(uint32_t)); 3506 rtDwarfUnwind_UpdateX86RFlagsFromRow(pState, &Old, pRow, DWREG_X86_EFLAGS, pCie, uCfa, pfnGetReg); 3507 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xAX, pRow, DWREG_X86_EAX, pCie, uCfa, pfnGetReg, sizeof(uint32_t)); 3508 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xCX, pRow, DWREG_X86_ECX, pCie, uCfa, pfnGetReg, sizeof(uint32_t)); 3509 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xDX, pRow, DWREG_X86_EDX, pCie, uCfa, pfnGetReg, sizeof(uint32_t)); 3510 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xBX, pRow, DWREG_X86_EBX, pCie, uCfa, pfnGetReg, sizeof(uint32_t)); 3511 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xSP, pRow, DWREG_X86_ESP, pCie, uCfa, pfnGetReg, sizeof(uint32_t)); 3512 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xBP, pRow, DWREG_X86_EBP, pCie, uCfa, pfnGetReg, sizeof(uint32_t)); 3513 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xSI, pRow, DWREG_X86_ESI, pCie, uCfa, pfnGetReg, sizeof(uint32_t)); 3514 rtDwarfUnwind_UpdateX86GRegFromRow(pState, &Old, X86_GREG_xDI, pRow, DWREG_X86_EDI, pCie, uCfa, pfnGetReg, sizeof(uint32_t)); 3515 rtDwarfUnwind_UpdateX86SRegFromRow(pState, &Old, X86_SREG_ES, pRow, DWREG_X86_ES, pCie, uCfa, pfnGetReg); 3516 rtDwarfUnwind_UpdateX86SRegFromRow(pState, &Old, X86_SREG_CS, pRow, DWREG_X86_CS, pCie, uCfa, pfnGetReg); 3517 rtDwarfUnwind_UpdateX86SRegFromRow(pState, &Old, X86_SREG_SS, pRow, DWREG_X86_SS, pCie, uCfa, pfnGetReg); 3518 rtDwarfUnwind_UpdateX86SRegFromRow(pState, &Old, X86_SREG_DS, pRow, DWREG_X86_DS, pCie, uCfa, pfnGetReg); 3519 rtDwarfUnwind_UpdateX86SRegFromRow(pState, &Old, X86_SREG_FS, pRow, DWREG_X86_FS, pCie, uCfa, pfnGetReg); 3520 rtDwarfUnwind_UpdateX86SRegFromRow(pState, &Old, X86_SREG_GS, pRow, DWREG_X86_GS, pCie, uCfa, pfnGetReg); 3521 break; 3522 3523 default: 3524 AssertFailedReturn(VERR_NOT_SUPPORTED); 3525 } 3526 3527 return VINF_SUCCESS; 3528 } 3529 2586 3530 2587 3531 /** … … 2636 3580 2637 3581 /* 2638 * The crazy part. Table program execution.3582 * Now "execute" the programs till we've constructed the desired row. 2639 3583 */ 2640 if (pCie->cbInstructions > 0) 2641 { 2642 /** @todo continue here later. */ 2643 } 3584 RTDWARFCFROW Row; 3585 RTDWARFCFEXEC ExecState = { &Row, offInRange, 0, true /** @todo byte-order*/, pCie, uPcBegin, offInRange }; 3586 RT_ZERO(Row); 3587 3588 int rc = rtDwarfUnwind_Execute(&ExecState, pCie->pbInstructions, (uint32_t)pCie->cbInstructions); 3589 if (rc == VINF_TRY_AGAIN) 3590 rc = rtDwarfUnwind_Execute(&ExecState, pCursor->pb, (uint32_t)pCursor->cbUnitLeft); 3591 3592 /* On success, extract whatever state we've got. */ 3593 if (RT_SUCCESS(rc)) 3594 rc = rtDwarfUnwind_UpdateStateFromRow(pState, &Row, pCie); 3595 3596 /* 3597 * Clean up allocations in case of pushes. 3598 */ 3599 if (ExecState.pRow == &Row) 3600 Assert(!ExecState.pRow->fOnHeap); 3601 else 3602 do 3603 { 3604 PRTDWARFCFROW pPopped = ExecState.pRow; 3605 ExecState.pRow = ExecState.pRow->pNextOnStack; 3606 Assert(pPopped->fOnHeap); 3607 RTMemTmpFree(pPopped); 3608 } while (ExecState.pRow && ExecState.pRow != &Row); 2644 3609 2645 3610 RT_NOREF(pState, uPcBegin, cbPcRange, offInRange); 2646 return VINF_SUCCESS; 2647 } 2648 3611 return rc; 3612 } 2649 3613 2650 3614 … … 2663 3627 static int rtDwarfUnwind_LoadCie(PRTDWARFCURSOR pCursor, PRTDWARFCIEINFO pNewCie, uint64_t offUnit, uint8_t bDefaultPtrEnc) 2664 3628 { 3629 Log8(("%#08RX64: rtDwarfUnwind_LoadCie: %.*Rhxs\n", offUnit, pCursor->cbUnitLeft, pCursor->pb)); 2665 3630 /* 2666 3631 * Initialize the CIE record and get the version. … … 2673 3638 if ( pNewCie->uDwarfVer >= 1 /* Note! Some GCC versions may emit v1 here. */ 2674 3639 && pNewCie->uDwarfVer <= 5) 3640 { /* likely */ } 3641 else 3642 { 3643 Log(("rtDwarfUnwind_LoadCie(%RX64): uDwarfVer=%u: VERR_VERSION_MISMATCH\n", offUnit, pNewCie->uDwarfVer)); 2675 3644 return VERR_VERSION_MISMATCH; 3645 } 2676 3646 2677 3647 /* … … 2727 3697 pNewCie->uCodeAlignFactor = rtDwarfCursor_GetULeb128(pCursor, 1); 2728 3698 pNewCie->iDataAlignFactor = rtDwarfCursor_GetSLeb128(pCursor, 1); 3699 pNewCie->bRetReg = rtDwarfCursor_GetU8(pCursor, UINT8_MAX); 2729 3700 2730 3701 /* … … 2739 3710 uint64_t cbAugData = rtDwarfCursor_GetULeb128(pCursor, UINT64_MAX); 2740 3711 if (RT_FAILURE(pCursor->rc)) 3712 { 3713 Log(("rtDwarfUnwind_LoadCie(%#RX64): rtDwarfCursor_GetULeb128 -> %Rrc!\n", offUnit, pCursor->rc)); 2741 3714 return pCursor->rc; 3715 } 2742 3716 if (cbAugData > pCursor->cbUnitLeft) 3717 { 3718 Log(("rtDwarfUnwind_LoadCie(%#RX64): cbAugData=%#x pCursor->cbUnitLeft=%#x -> VERR_DBG_MALFORMED_UNWIND_INFO!\n", offUnit, cbAugData, pCursor->cbUnitLeft)); 2743 3719 return VERR_DBG_MALFORMED_UNWIND_INFO; 3720 } 2744 3721 cbInstr = pCursor->cbUnitLeft - cbAugData; 2745 3722 } 2746 3723 else if (pNewCie->fHasUnknowAugmentation) 3724 { 3725 Log(("rtDwarfUnwind_LoadCie(%#RX64): fHasUnknowAugmentation=%1 -> VERR_DBG_MALFORMED_UNWIND_INFO!\n", offUnit)); 2747 3726 return VERR_DBG_MALFORMED_UNWIND_INFO; 3727 } 2748 3728 2749 3729 /* Parse the string. */ … … 2775 3755 2776 3756 /* 2777 * Determine the target address encoding. 3757 * Determine the target address encoding. Make sure we resolve DW_EH_PE_ptr. 2778 3758 */ 2779 3759 if (pNewCie->bAddressPtrEnc == DW_EH_PE_omit) … … 2785 3765 default: pNewCie->bAddressPtrEnc = bDefaultPtrEnc; break; 2786 3766 } 3767 else if ((pNewCie->bAddressPtrEnc & DW_EH_PE_FORMAT_MASK) == DW_EH_PE_ptr) 3768 pNewCie->bAddressPtrEnc = bDefaultPtrEnc; 2787 3769 2788 3770 return VINF_SUCCESS; … … 2795 3777 * @returns IPRT status code. 2796 3778 * @param pCursor The cursor. 3779 * @param uRvaCursor The RVA corrsponding to the cursor start location. 2797 3780 * @param idxSeg The segment of the PC location. 2798 3781 * @param offSeg The segment offset of the PC location. … … 2803 3786 * with different CIE_pointer values. 2804 3787 */ 2805 DECLHIDDEN(int) rtDwarfUnwind_Slow(PRTDWARFCURSOR pCursor, RTDBGSEGIDX idxSeg, RTUINTPTR offSeg, RTUINTPTR uRva, 3788 DECLHIDDEN(int) rtDwarfUnwind_Slow(PRTDWARFCURSOR pCursor, RTUINTPTR uRvaCursor, 3789 RTDBGSEGIDX idxSeg, RTUINTPTR offSeg, RTUINTPTR uRva, 2806 3790 PRTDBGUNWINDSTATE pState, uint8_t bDefaultPtrEnc, bool fIsEhFrame) 2807 3791 { 3792 Log8(("rtDwarfUnwind_Slow: idxSeg=%#x offSeg=%RTptr uRva=%RTptr enmArch=%d PC=%#RX64\n", idxSeg, offSeg, uRva, pState->enmArch, pState->uPc)); 3793 2808 3794 /* 2809 3795 * CIE info we collect. … … 2817 3803 */ 2818 3804 int rc = VERR_DBG_UNWIND_INFO_NOT_FOUND; 2819 while ( !rtDwarfCursor_IsAtEnd(pCursor) 2820 && RT_SUCCESS(rc)) 3805 while (!rtDwarfCursor_IsAtEnd(pCursor)) 2821 3806 { 2822 3807 uint64_t const offUnit = rtDwarfCursor_CalcSectOffsetU32(pCursor); 2823 if (rtDwarfCursor_GetInit alLength(pCursor) == 0)3808 if (rtDwarfCursor_GetInitialLength(pCursor) == 0) 2824 3809 break; 3810 Log8(("%#08RX64: rtDwarfCursor_GetInitialLength -> %#x\n", offUnit, pCursor->cbUnitLeft)); 2825 3811 2826 3812 uint64_t const offRelCie = rtDwarfCursor_GetUOff(pCursor, 0); … … 2834 3820 in .eh_frame and section relative in .debug_frame. */ 2835 3821 PRTDWARFCIEINFO pCieForFde; 2836 uint64_t offCie = fIsEhFrame ? offUnit - offRelCie : offRelCie;3822 uint64_t offCie = fIsEhFrame ? offUnit + 4 - offRelCie : offRelCie; 2837 3823 if (pCieHint && pCieHint->offCie == offCie) 2838 3824 pCieForFde = pCieHint; … … 2850 3836 if (pCieForFde) 2851 3837 { 2852 /* Read the PC range covered by this FDE (the fields are also 2853 known as initial_location & instructions). */ 3838 /* Read the PC range covered by this FDE (the fields are also known as initial_location). */ 2854 3839 RTDBGSEGIDX idxFdeSeg = RTDBGSEGIDX_RVA; 2855 3840 if (pCieForFde->cbSegment) 2856 3841 idxFdeSeg = rtDwarfCursor_GetVarSizedU(pCursor, pCieForFde->cbSegment, RTDBGSEGIDX_RVA); 2857 uint64_t uPcBegin = rtDwarfCursor_GetPtrEnc(pCursor, pCieForFde->bAddressPtrEnc, 0); 3842 uint64_t uPcBegin; 3843 switch (pCieForFde->bAddressPtrEnc & DW_EH_PE_APPL_MASK) 3844 { 3845 default: AssertFailed(); 3846 RT_FALL_THRU(); 3847 case DW_EH_PE_absptr: 3848 uPcBegin = rtDwarfCursor_GetPtrEnc(pCursor, pCieForFde->bAddressPtrEnc, 0); 3849 break; 3850 case DW_EH_PE_pcrel: 3851 { 3852 uPcBegin = rtDwarfCursor_CalcSectOffsetU32(pCursor) + uRvaCursor; 3853 uPcBegin += rtDwarfCursor_GetPtrEnc(pCursor, pCieForFde->bAddressPtrEnc, 0); 3854 break; 3855 } 3856 } 2858 3857 uint64_t cbPcRange = rtDwarfCursor_GetPtrEnc(pCursor, pCieForFde->bAddressPtrEnc, 0); 2859 3858 … … 2862 3861 ? uRva - uPcBegin < cbPcRange 2863 3862 : idxSeg == idxFdeSeg && offSeg - uPcBegin < cbPcRange; 3863 Log8(("%#08RX64: FDE pCie=%p idxFdeSeg=%#x uPcBegin=%#RX64 cbPcRange=%#x fMatch=%d\n", 3864 offUnit, pCieForFde, idxFdeSeg, uPcBegin, cbPcRange, fMatch)); 2864 3865 if (fMatch) 2865 3866 { … … 2870 3871 } 2871 3872 } 3873 else 3874 Log8(("%#08RX64: FDE - pCie=NULL!! offCie=%#RX64 offRelCie=%#RX64 fIsEhFrame=%d\n", offUnit, offCie, offRelCie, fIsEhFrame)); 2872 3875 } 2873 3876 else … … 2887 3890 } 2888 3891 } 3892 Log8(("%#08RX64: CIE\n", offUnit)); 2889 3893 int rc2 = rtDwarfUnwind_LoadCie(pCursor, &paCies[cCies], offUnit, bDefaultPtrEnc); 2890 3894 if (RT_SUCCESS(rc2)) 3895 { 3896 Log8(("%#08RX64: CIE #%u: offCie=%#RX64\n", offUnit, cCies, paCies[cCies].offCie)); 2891 3897 cCies++; 3898 } 2892 3899 } 2893 3900 rtDwarfCursor_SkipUnit(pCursor); … … 2899 3906 if (paCies) 2900 3907 RTMemFree(paCies); 3908 Log8(("rtDwarfUnwind_Slow: returns %Rrc PC=%#RX64\n", rc, pState->uPc)); 2901 3909 return rc; 2902 3910 } … … 2938 3946 * @param pvSection The '.eh_frame' section data. 2939 3947 * @param cbSection The size of the '.eh_frame' section data. 3948 * @param uRvaSection The RVA of the '.eh_frame' section. 2940 3949 * @param idxSeg The segment of the PC location. 2941 3950 * @param offSeg The segment offset of the PC location. … … 2944 3953 * @param enmArch The image architecture. 2945 3954 */ 2946 DECLHIDDEN(int) rtDwarfUnwind_EhData(void const *pvSection, size_t cbSection, RTDBGSEGIDX idxSeg, RTUINTPTR offSeg, 2947 RTUINTPTR uRva, PRTDBGUNWINDSTATE pState, RTLDRARCH enmArch) 3955 DECLHIDDEN(int) rtDwarfUnwind_EhData(void const *pvSection, size_t cbSection, RTUINTPTR uRvaSection, 3956 RTDBGSEGIDX idxSeg, RTUINTPTR offSeg, RTUINTPTR uRva, 3957 PRTDBGUNWINDSTATE pState, RTLDRARCH enmArch) 2948 3958 { 2949 3959 RTDWARFCURSOR Cursor; 2950 3960 rtDwarfCursor_InitForMem(&Cursor, pvSection, cbSection); 2951 int rc = rtDwarfUnwind_Slow(&Cursor, idxSeg, offSeg, uRva, pState, rtDwarfUnwind_ArchToPtrEnc(enmArch), true /*fIsEhFrame*/); 2952 return rtDwarfCursor_Delete(&Cursor, rc); 3961 int rc = rtDwarfUnwind_Slow(&Cursor, uRvaSection, idxSeg, offSeg, uRva, pState, 3962 rtDwarfUnwind_ArchToPtrEnc(enmArch), true /*fIsEhFrame*/); 3963 LogFlow(("rtDwarfUnwind_EhData: rtDwarfUnwind_Slow -> %Rrc\n", rc)); 3964 rc = rtDwarfCursor_Delete(&Cursor, rc); 3965 LogFlow(("rtDwarfUnwind_EhData: returns %Rrc\n", rc)); 3966 return rc; 2953 3967 } 2954 3968 … … 3398 4412 * Parse the header. 3399 4413 */ 3400 rtDwarfCursor_GetInit alLength(pCursor);4414 rtDwarfCursor_GetInitialLength(pCursor); 3401 4415 LnState.Hdr.uVer = rtDwarfCursor_GetUHalf(pCursor, 0); 3402 4416 if ( LnState.Hdr.uVer < 2 … … 4953 5967 */ 4954 5968 uint64_t offUnit = rtDwarfCursor_CalcSectOffsetU32(pCursor); 4955 uint64_t cbUnit = rtDwarfCursor_GetInit alLength(pCursor);5969 uint64_t cbUnit = rtDwarfCursor_GetInitialLength(pCursor); 4956 5970 cbUnit += rtDwarfCursor_CalcSectOffsetU32(pCursor) - offUnit; 4957 5971 uint16_t const uVer = rtDwarfCursor_GetUHalf(pCursor, 0); … … 5243 6257 5244 6258 /* Do the work */ 5245 rc = rtDwarfUnwind_Slow(&Cursor, iSeg, off, uRva, pState, bPtrEnc, false /*fIsEhFrame*/); 6259 rc = rtDwarfUnwind_Slow(&Cursor, 0 /** @todo .debug_frame RVA*/, iSeg, off, uRva, 6260 pState, bPtrEnc, false /*fIsEhFrame*/); 5246 6261 5247 6262 rc = rtDwarfCursor_Delete(&Cursor, rc); -
trunk/src/VBox/Runtime/common/dbg/dbgstackdumpself-amd64-x86.asm
r74255 r75235 80 80 SEH64_PUSH_GREG xSI 81 81 %ifdef RT_ARCH_AMD64 82 mov r10, [xBP + xCB * 2]; Caller RBP.82 mov r10, [xBP] ; Caller RBP. 83 83 push r10 84 84 lea r10, [xBP + xCB * 2] ; Caller RSP. -
trunk/src/VBox/Runtime/common/dbg/dbgstackdumpself.cpp
r74252 r75235 47 47 # include <iprt/param.h> 48 48 # include <iprt/win/windows.h> 49 #elif defined(RT_OS_LINUX) 50 # include <dlfcn.h> 49 51 #endif 50 52 … … 273 275 RTMemFree(pMod); 274 276 } 277 } 278 } 279 #elif defined(RT_OS_LINUX) 280 Dl_info Info = { NULL, NULL, NULL, NULL }; 281 int rc = dladdr((const void *)uPc, &Info); 282 if (rc != 0) 283 { 284 pMod = (PRTDBGSTACKSELFMOD)RTMemAllocZ(sizeof(*pMod)); 285 if (pMod) 286 { 287 /** @todo better filename translation... */ 288 rc = RTStrCopy(pMod->szFilename, sizeof(pMod->szFilename), Info.dli_fname); 289 if (RT_SUCCESS(rc)) 290 { 291 RTStrPurgeEncoding(pMod->szFilename); 292 293 const char *pszFilename = RTPathFilename(pMod->szFilename); 294 pMod->offName = pszFilename ? pszFilename - &pMod->szFilename[0] : 0; 295 pMod->uMapping = (uintptr_t)Info.dli_fbase; 296 pMod->cbMapping = 0; 297 pMod->hLdrMod = NIL_RTLDRMOD; 298 pMod->hDbgMod = NIL_RTDBGMOD; 299 300 rc = RTLdrOpen(pMod->szFilename, RTLDR_O_FOR_DEBUG, RTLdrGetHostArch(), &pMod->hLdrMod); 301 if (RT_SUCCESS(rc)) 302 { 303 pMod->cbMapping = RTLdrSize(pMod->hLdrMod); 304 305 /* Try open debug info for the module. */ 306 //uint32_t uTimeDateStamp = 0; 307 //RTLdrQueryProp(pMod->hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &uTimeDateStamp, sizeof(uTimeDateStamp)); 308 //RTDbgModCreateFromImage()?? 309 //rc = RTDbgModCreateFromPeImage(&pMod->hDbgMod, pMod->szFilename, &pMod->szFilename[pMod->offName], 310 // &pMod->hLdrMod, (uint32_t)pMod->cbMapping, uTimeDateStamp, NIL_RTDBGCFG); 311 312 RTListPrepend(pCachedModules, &pMod->ListEntry); 313 return pMod; 314 } 315 } 316 RTMemFree(pMod); 275 317 } 276 318 } -
trunk/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h
r73531 r75235 1419 1419 int rc; 1420 1420 RTLDRADDR uRva = off; 1421 if (iSeg == RTDBGSEGIDX_RVA)1421 if (iSeg == UINT32_MAX) 1422 1422 rc = RTLDRELF_NAME(RvaToSegOffset)(pMod, uRva, &iSeg, &off); 1423 1423 else … … 1454 1454 && pszName[8] == 'e') 1455 1455 { 1456 if (pszName[ 8] == '\0')1456 if (pszName[9] == '\0') 1457 1457 pThis->iShEhFrame = iShdr; 1458 else if ( pszName[ 8] == '_'1459 && pszName[ 9] == 'h'1460 && pszName[1 0] == 'd'1461 && pszName[1 1] == 'r'1462 && pszName[1 2] == '\0')1458 else if ( pszName[9] == '_' 1459 && pszName[10] == 'h' 1460 && pszName[11] == 'd' 1461 && pszName[12] == 'r' 1462 && pszName[13] == '\0') 1463 1463 pThis->iShEhFrameHdr = iShdr; 1464 1464 else … … 1479 1479 if (pThis->paShdrs[iShdr].sh_flags & SHF_ALLOC) 1480 1480 return rtDwarfUnwind_EhData((uint8_t const *)pThis->pvBits + pThis->paShdrs[iShdr].sh_addr, 1481 pThis->paShdrs[iShdr].sh_size, iSeg, off, uRva, pState, pThis->Core.enmArch); 1481 pThis->paShdrs[iShdr].sh_size, pThis->paShdrs[iShdr].sh_addr, 1482 iSeg, off, uRva, pState, pThis->Core.enmArch); 1482 1483 } 1483 1484 return VERR_DBG_NO_UNWIND_INFO; 1484 1485 } 1485 1486 1487 1486 1488 1487 … … 1980 1979 rc = VERR_LDR_GENERAL_FAILURE; 1981 1980 } 1981 if (pModElf->Ehdr.e_type == ET_DYN && pModElf->LinkAddress < 0x1000) 1982 pModElf->LinkAddress = 0; 1982 1983 } 1983 1984 -
trunk/src/VBox/Runtime/common/misc/assert.cpp
r74344 r75235 143 143 #ifdef IPRT_WITH_ASSERT_STACK 144 144 /* The stack dump. */ 145 static volatile bool s_fDumpingStackAlready = false; /* for simple recursion prevention */ 145 146 char szStack[sizeof(g_szRTAssertStack)]; 146 147 size_t cchStack = 0; … … 152 153 bool fStack = true; 153 154 # endif 154 if (fStack) 155 szStack[0] = '\0'; 156 if (fStack && !s_fDumpingStackAlready) 157 { 158 s_fDumpingStackAlready = true; 155 159 cchStack = RTDbgStackDumpSelf(szStack, sizeof(szStack), 0); 156 else157 szStack[0] = '\0';160 s_fDumpingStackAlready = false; 161 } 158 162 memcpy(g_szRTAssertStack, szStack, cchStack + 1); 159 163 #endif
Note:
See TracChangeset
for help on using the changeset viewer.