@@ -62,12 +62,26 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
62
62
63
63
SET_DEFAULT_DEBUG_CHANNEL (EXCEPT);
64
64
65
- // Only used on the AMD64 build
66
- #if defined(_AMD64_) && defined(HAVE_UNW_GET_ACCESSORS)
65
+ // Only used on the AMD64/ARM64 builds - ARM32 uses EXIDX which isn't currently supported
66
+ #if ( defined(_AMD64_) || defined(_ARM64_) ) && defined(HAVE_UNW_GET_ACCESSORS)
67
67
68
68
#include < elf.h>
69
69
#include < link.h>
70
70
71
+ #if defined(_X86_) || defined(_ARM_)
72
+ #define PRIx PRIx32
73
+ #define PRIu PRIu32
74
+ #define PRId PRId32
75
+ #define PRIA " 08"
76
+ #define PRIxA PRIA PRIx
77
+ #elif defined(_AMD64_) || defined(_ARM64_)
78
+ #define PRIx PRIx64
79
+ #define PRIu PRIu64
80
+ #define PRId PRId64
81
+ #define PRIA " 016"
82
+ #define PRIxA PRIA PRIx
83
+ #endif
84
+
71
85
#ifndef ElfW
72
86
#define ElfW (foo ) Elf_ ## foo
73
87
#endif
@@ -77,7 +91,6 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT);
77
91
#define Nhdr ElfW (Nhdr)
78
92
#define Dyn ElfW (Dyn)
79
93
80
- extern void UnwindContextToWinContext(unw_cursor_t *cursor, CONTEXT *winContext);
81
94
extern void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext, KNONVOLATILE_CONTEXT_POINTERS *contextPointers);
82
95
83
96
typedef struct _libunwindInfo
@@ -128,7 +141,7 @@ typedef struct _libunwindInfo
128
141
#define DWARF_CIE_VERSION 3 // GCC emits version 1???
129
142
130
143
// DWARF frame header
131
- typedef struct _eh_frame_hdr
144
+ typedef struct __attribute__ ((packed)) _eh_frame_hdr
132
145
{
133
146
unsigned char version;
134
147
unsigned char eh_frame_ptr_enc;
@@ -764,6 +777,37 @@ ExtractProcInfoFromFde(const libunwindInfo* info, unw_word_t* addrp, unw_proc_in
764
777
return true ;
765
778
}
766
779
780
+ static void UnwindContextToContext (unw_cursor_t *cursor, CONTEXT *winContext)
781
+ {
782
+ #if defined(_AMD64_)
783
+ unw_get_reg (cursor, UNW_REG_IP, (unw_word_t *) &winContext->Rip );
784
+ unw_get_reg (cursor, UNW_REG_SP, (unw_word_t *) &winContext->Rsp );
785
+ unw_get_reg (cursor, UNW_X86_64_RBP, (unw_word_t *) &winContext->Rbp );
786
+ unw_get_reg (cursor, UNW_X86_64_RBX, (unw_word_t *) &winContext->Rbx );
787
+ unw_get_reg (cursor, UNW_X86_64_R12, (unw_word_t *) &winContext->R12 );
788
+ unw_get_reg (cursor, UNW_X86_64_R13, (unw_word_t *) &winContext->R13 );
789
+ unw_get_reg (cursor, UNW_X86_64_R14, (unw_word_t *) &winContext->R14 );
790
+ unw_get_reg (cursor, UNW_X86_64_R15, (unw_word_t *) &winContext->R15 );
791
+ #elif defined(_ARM64_)
792
+ unw_get_reg (cursor, UNW_REG_IP, (unw_word_t *) &winContext->Pc );
793
+ unw_get_reg (cursor, UNW_REG_SP, (unw_word_t *) &winContext->Sp );
794
+ unw_get_reg (cursor, UNW_AARCH64_X19, (unw_word_t *) &winContext->X19 );
795
+ unw_get_reg (cursor, UNW_AARCH64_X20, (unw_word_t *) &winContext->X20 );
796
+ unw_get_reg (cursor, UNW_AARCH64_X21, (unw_word_t *) &winContext->X21 );
797
+ unw_get_reg (cursor, UNW_AARCH64_X22, (unw_word_t *) &winContext->X22 );
798
+ unw_get_reg (cursor, UNW_AARCH64_X23, (unw_word_t *) &winContext->X23 );
799
+ unw_get_reg (cursor, UNW_AARCH64_X24, (unw_word_t *) &winContext->X24 );
800
+ unw_get_reg (cursor, UNW_AARCH64_X25, (unw_word_t *) &winContext->X25 );
801
+ unw_get_reg (cursor, UNW_AARCH64_X26, (unw_word_t *) &winContext->X26 );
802
+ unw_get_reg (cursor, UNW_AARCH64_X27, (unw_word_t *) &winContext->X27 );
803
+ unw_get_reg (cursor, UNW_AARCH64_X28, (unw_word_t *) &winContext->X28 );
804
+ unw_get_reg (cursor, UNW_AARCH64_X29, (unw_word_t *) &winContext->Fp );
805
+ unw_get_reg (cursor, UNW_AARCH64_X30, (unw_word_t *) &winContext->Lr );
806
+ TRACE (" sp %p pc %p lr %p fp %p\n " , winContext->Sp , winContext->Pc , winContext->Lr , winContext->Fp );
807
+ #else
808
+ #error unsupported architecture
809
+ #endif
810
+ }
767
811
768
812
static int
769
813
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dilap, void *arg)
@@ -827,8 +871,8 @@ access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t *valp, int write
827
871
case UNW_ARM_R10: *valp = (unw_word_t )winContext->R10 ; break ;
828
872
case UNW_ARM_R11: *valp = (unw_word_t )winContext->R11 ; break ;
829
873
#elif defined(_ARM64_)
830
- case UNW_REG_IP : *valp = (unw_word_t )winContext->Pc ; break ;
831
- case UNW_REG_SP : *valp = (unw_word_t )winContext->Sp ; break ;
874
+ case UNW_AARCH64_SP : *valp = (unw_word_t )winContext->Sp ; break ;
875
+ case UNW_AARCH64_PC : *valp = (unw_word_t )winContext->Pc ; break ;
832
876
case UNW_AARCH64_X29: *valp = (unw_word_t )winContext->Fp ; break ;
833
877
case UNW_AARCH64_X30: *valp = (unw_word_t )winContext->Lr ; break ;
834
878
case UNW_AARCH64_X19: *valp = (unw_word_t )winContext->X19 ; break ;
@@ -845,9 +889,10 @@ access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t *valp, int write
845
889
#error unsupported architecture
846
890
#endif
847
891
default :
848
- ASSERT (" Attempt to read an unknown register\n " );
892
+ ASSERT (" Attempt to read an unknown register %d \n " , regnum );
849
893
return -UNW_EBADREG;
850
894
}
895
+ TRACE (" REG: %d %p\n " , regnum, *valp);
851
896
return UNW_ESUCCESS;
852
897
}
853
898
@@ -901,7 +946,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pip, int nee
901
946
ERROR (" ELF: reading phdrAddr %p\n " , phdrAddr);
902
947
return -UNW_EINVAL;
903
948
}
904
- TRACE (" ELF: phdr %p type %d (%x) vaddr %p memsz %016llx paddr %p filesz %016llx offset %p align %016llx \n " ,
949
+ TRACE (" ELF: phdr %p type %d (%x) vaddr %" PRIxA " memsz %" PRIxA " paddr %" PRIxA " filesz %" PRIxA " offset %" PRIxA " align %" PRIxA " \n " ,
905
950
phdrAddr, ph.p_type , ph.p_type , ph.p_vaddr , ph.p_memsz , ph.p_paddr , ph.p_filesz , ph.p_offset , ph.p_align );
906
951
907
952
switch (ph.p_type )
@@ -941,6 +986,11 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pip, int nee
941
986
dynamicAddr++;
942
987
}
943
988
}
989
+
990
+ if (ehPhdr.p_offset == 0 ) {
991
+ ASSERT (" ELF: No PT_GNU_EH_FRAME program header\n " );
992
+ return -UNW_EINVAL;
993
+ }
944
994
unw_word_t ehFrameHdrAddr = ehPhdr.p_offset + info->BaseAddress ;
945
995
eh_frame_hdr ehFrameHdr;
946
996
@@ -970,6 +1020,12 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pip, int nee
970
1020
}
971
1021
TRACE (" ehFrameStart %p fdeCount %p ip offset %08x\n " , ehFrameStart, fdeCount, (int32_t )(ip - ehFrameHdrAddr));
972
1022
1023
+ // If there are no frame table entries
1024
+ if (fdeCount == 0 ) {
1025
+ TRACE (" No frame table entries\n " );
1026
+ return -UNW_ENOINFO;
1027
+ }
1028
+
973
1029
// LookupTableEntry assumes this encoding
974
1030
if (ehFrameHdr.table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) {
975
1031
ASSERT (" Table encoding not supported %x\n " , ehFrameHdr.table_enc );
@@ -996,7 +1052,10 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pip, int nee
996
1052
return -UNW_EINVAL;
997
1053
}
998
1054
999
- _ASSERTE (ip >= pip->start_ip && ip <= pip->end_ip );
1055
+ if (ip < pip->start_ip || ip >= pip->end_ip ) {
1056
+ TRACE (" ip %p not in range start_ip %p end_ip %p\n " , ip, pip->start_ip , pip->end_ip );
1057
+ return -UNW_ENOINFO;
1058
+ }
1000
1059
return UNW_ESUCCESS;
1001
1060
}
1002
1061
@@ -1066,7 +1125,7 @@ PAL_VirtualUnwindOutOfProc(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *cont
1066
1125
goto exit;
1067
1126
}
1068
1127
1069
- UnwindContextToWinContext (&cursor, context);
1128
+ UnwindContextToContext (&cursor, context);
1070
1129
1071
1130
if (contextPointers != NULL )
1072
1131
{
0 commit comments