aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/unwind.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2006-12-06 20:14:13 -0500
committerAndi Kleen <andi@basil.nowhere.org>2006-12-06 20:14:13 -0500
commit6d0185ea611276fdf81991d7774d396bdc1ae392 (patch)
treecfbea72e9df3816a63ba6debd3e591d89b2c63e1 /kernel/unwind.c
parent3807fd46e94ab9f09e5ee3bff5e6515a94e9b3c7 (diff)
[PATCH] unwinder: Add debugging output to the Dwarf2 unwinder
Add debugging printks to the unwinder to allow easier debugging when something goes wrong with it. This can be controlled with the new unwinder_debug=N option Most output is given by N=1 AK: Added documentation of unwinder_debug= Signed-off-by: Jan Beulich <jbeulich@novell.com> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'kernel/unwind.c')
-rw-r--r--kernel/unwind.c113
1 files changed, 96 insertions, 17 deletions
diff --git a/kernel/unwind.c b/kernel/unwind.c
index 7e721f104105..209e248517db 100644
--- a/kernel/unwind.c
+++ b/kernel/unwind.c
@@ -137,6 +137,17 @@ struct unwind_state {
137 137
138static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 }; 138static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 };
139 139
140static unsigned unwind_debug;
141static int __init unwind_debug_setup(char *s)
142{
143 unwind_debug = simple_strtoul(s, NULL, 0);
144 return 1;
145}
146__setup("unwind_debug=", unwind_debug_setup);
147#define dprintk(lvl, fmt, args...) \
148 ((void)(lvl > unwind_debug \
149 || printk(KERN_DEBUG "unwind: " fmt "\n", ##args)))
150
140static struct unwind_table *find_table(unsigned long pc) 151static struct unwind_table *find_table(unsigned long pc)
141{ 152{
142 struct unwind_table *table; 153 struct unwind_table *table;
@@ -281,6 +292,7 @@ static void __init setup_unwind_table(struct unwind_table *table,
281 292
282 hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int) 293 hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
283 + 2 * n * sizeof(unsigned long); 294 + 2 * n * sizeof(unsigned long);
295 dprintk(2, "Binary lookup table size for %s: %lu bytes", table->name, hdrSize);
284 header = alloc(hdrSize); 296 header = alloc(hdrSize);
285 if (!header) 297 if (!header)
286 return; 298 return;
@@ -500,13 +512,17 @@ static unsigned long read_pointer(const u8 **pLoc,
500 const unsigned long *pul; 512 const unsigned long *pul;
501 } ptr; 513 } ptr;
502 514
503 if (ptrType < 0 || ptrType == DW_EH_PE_omit) 515 if (ptrType < 0 || ptrType == DW_EH_PE_omit) {
516 dprintk(1, "Invalid pointer encoding %02X (%p,%p).", ptrType, *pLoc, end);
504 return 0; 517 return 0;
518 }
505 ptr.p8 = *pLoc; 519 ptr.p8 = *pLoc;
506 switch(ptrType & DW_EH_PE_FORM) { 520 switch(ptrType & DW_EH_PE_FORM) {
507 case DW_EH_PE_data2: 521 case DW_EH_PE_data2:
508 if (end < (const void *)(ptr.p16u + 1)) 522 if (end < (const void *)(ptr.p16u + 1)) {
523 dprintk(1, "Data16 overrun (%p,%p).", ptr.p8, end);
509 return 0; 524 return 0;
525 }
510 if(ptrType & DW_EH_PE_signed) 526 if(ptrType & DW_EH_PE_signed)
511 value = get_unaligned(ptr.p16s++); 527 value = get_unaligned(ptr.p16s++);
512 else 528 else
@@ -514,8 +530,10 @@ static unsigned long read_pointer(const u8 **pLoc,
514 break; 530 break;
515 case DW_EH_PE_data4: 531 case DW_EH_PE_data4:
516#ifdef CONFIG_64BIT 532#ifdef CONFIG_64BIT
517 if (end < (const void *)(ptr.p32u + 1)) 533 if (end < (const void *)(ptr.p32u + 1)) {
534 dprintk(1, "Data32 overrun (%p,%p).", ptr.p8, end);
518 return 0; 535 return 0;
536 }
519 if(ptrType & DW_EH_PE_signed) 537 if(ptrType & DW_EH_PE_signed)
520 value = get_unaligned(ptr.p32s++); 538 value = get_unaligned(ptr.p32s++);
521 else 539 else
@@ -527,8 +545,10 @@ static unsigned long read_pointer(const u8 **pLoc,
527 BUILD_BUG_ON(sizeof(u32) != sizeof(value)); 545 BUILD_BUG_ON(sizeof(u32) != sizeof(value));
528#endif 546#endif
529 case DW_EH_PE_native: 547 case DW_EH_PE_native:
530 if (end < (const void *)(ptr.pul + 1)) 548 if (end < (const void *)(ptr.pul + 1)) {
549 dprintk(1, "DataUL overrun (%p,%p).", ptr.p8, end);
531 return 0; 550 return 0;
551 }
532 value = get_unaligned(ptr.pul++); 552 value = get_unaligned(ptr.pul++);
533 break; 553 break;
534 case DW_EH_PE_leb128: 554 case DW_EH_PE_leb128:
@@ -536,10 +556,14 @@ static unsigned long read_pointer(const u8 **pLoc,
536 value = ptrType & DW_EH_PE_signed 556 value = ptrType & DW_EH_PE_signed
537 ? get_sleb128(&ptr.p8, end) 557 ? get_sleb128(&ptr.p8, end)
538 : get_uleb128(&ptr.p8, end); 558 : get_uleb128(&ptr.p8, end);
539 if ((const void *)ptr.p8 > end) 559 if ((const void *)ptr.p8 > end) {
560 dprintk(1, "DataLEB overrun (%p,%p).", ptr.p8, end);
540 return 0; 561 return 0;
562 }
541 break; 563 break;
542 default: 564 default:
565 dprintk(2, "Cannot decode pointer type %02X (%p,%p).",
566 ptrType, ptr.p8, end);
543 return 0; 567 return 0;
544 } 568 }
545 switch(ptrType & DW_EH_PE_ADJUST) { 569 switch(ptrType & DW_EH_PE_ADJUST) {
@@ -549,11 +573,16 @@ static unsigned long read_pointer(const u8 **pLoc,
549 value += (unsigned long)*pLoc; 573 value += (unsigned long)*pLoc;
550 break; 574 break;
551 default: 575 default:
576 dprintk(2, "Cannot adjust pointer type %02X (%p,%p).",
577 ptrType, *pLoc, end);
552 return 0; 578 return 0;
553 } 579 }
554 if ((ptrType & DW_EH_PE_indirect) 580 if ((ptrType & DW_EH_PE_indirect)
555 && probe_kernel_address((unsigned long *)value, value)) 581 && probe_kernel_address((unsigned long *)value, value)) {
582 dprintk(1, "Cannot read indirect value %lx (%p,%p).",
583 value, *pLoc, end);
556 return 0; 584 return 0;
585 }
557 *pLoc = ptr.p8; 586 *pLoc = ptr.p8;
558 587
559 return value; 588 return value;
@@ -702,8 +731,10 @@ static int processCFI(const u8 *start,
702 state->label = NULL; 731 state->label = NULL;
703 return 1; 732 return 1;
704 } 733 }
705 if (state->stackDepth >= MAX_STACK_DEPTH) 734 if (state->stackDepth >= MAX_STACK_DEPTH) {
735 dprintk(1, "State stack overflow (%p,%p).", ptr.p8, end);
706 return 0; 736 return 0;
737 }
707 state->stack[state->stackDepth++] = ptr.p8; 738 state->stack[state->stackDepth++] = ptr.p8;
708 break; 739 break;
709 case DW_CFA_restore_state: 740 case DW_CFA_restore_state:
@@ -718,8 +749,10 @@ static int processCFI(const u8 *start,
718 result = processCFI(start, end, 0, ptrType, state); 749 result = processCFI(start, end, 0, ptrType, state);
719 state->loc = loc; 750 state->loc = loc;
720 state->label = label; 751 state->label = label;
721 } else 752 } else {
753 dprintk(1, "State stack underflow (%p,%p).", ptr.p8, end);
722 return 0; 754 return 0;
755 }
723 break; 756 break;
724 case DW_CFA_def_cfa: 757 case DW_CFA_def_cfa:
725 state->cfa.reg = get_uleb128(&ptr.p8, end); 758 state->cfa.reg = get_uleb128(&ptr.p8, end);
@@ -751,6 +784,7 @@ static int processCFI(const u8 *start,
751 break; 784 break;
752 case DW_CFA_GNU_window_save: 785 case DW_CFA_GNU_window_save:
753 default: 786 default:
787 dprintk(1, "Unrecognized CFI op %02X (%p,%p).", ptr.p8[-1], ptr.p8 - 1, end);
754 result = 0; 788 result = 0;
755 break; 789 break;
756 } 790 }
@@ -766,12 +800,17 @@ static int processCFI(const u8 *start,
766 set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state); 800 set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state);
767 break; 801 break;
768 } 802 }
769 if (ptr.p8 > end) 803 if (ptr.p8 > end) {
804 dprintk(1, "Data overrun (%p,%p).", ptr.p8, end);
770 result = 0; 805 result = 0;
806 }
771 if (result && targetLoc != 0 && targetLoc < state->loc) 807 if (result && targetLoc != 0 && targetLoc < state->loc)
772 return 1; 808 return 1;
773 } 809 }
774 810
811 if (result && ptr.p8 < end)
812 dprintk(1, "Data underrun (%p,%p).", ptr.p8, end);
813
775 return result 814 return result
776 && ptr.p8 == end 815 && ptr.p8 == end
777 && (targetLoc == 0 816 && (targetLoc == 0
@@ -843,6 +882,8 @@ int unwind(struct unwind_frame_info *frame)
843 hdr[3]); 882 hdr[3]);
844 } 883 }
845 } 884 }
885 if(hdr && !fde)
886 dprintk(3, "Binary lookup for %lx failed.", pc);
846 887
847 if (fde != NULL) { 888 if (fde != NULL) {
848 cie = cie_for_fde(fde, table); 889 cie = cie_for_fde(fde, table);
@@ -864,6 +905,8 @@ int unwind(struct unwind_frame_info *frame)
864 fde = NULL; 905 fde = NULL;
865 } else 906 } else
866 fde = NULL; 907 fde = NULL;
908 if(!fde)
909 dprintk(1, "Binary lookup result for %lx discarded.", pc);
867 } 910 }
868 if (fde == NULL) { 911 if (fde == NULL) {
869 for (fde = table->address, tableSize = table->size; 912 for (fde = table->address, tableSize = table->size;
@@ -895,6 +938,8 @@ int unwind(struct unwind_frame_info *frame)
895 if (pc >= startLoc && pc < endLoc) 938 if (pc >= startLoc && pc < endLoc)
896 break; 939 break;
897 } 940 }
941 if(!fde)
942 dprintk(3, "Linear lookup for %lx failed.", pc);
898 } 943 }
899 } 944 }
900 if (cie != NULL) { 945 if (cie != NULL) {
@@ -928,6 +973,8 @@ int unwind(struct unwind_frame_info *frame)
928 if (ptr >= end || *ptr) 973 if (ptr >= end || *ptr)
929 cie = NULL; 974 cie = NULL;
930 } 975 }
976 if(!cie)
977 dprintk(1, "CIE unusable (%p,%p).", ptr, end);
931 ++ptr; 978 ++ptr;
932 } 979 }
933 if (cie != NULL) { 980 if (cie != NULL) {
@@ -938,9 +985,11 @@ int unwind(struct unwind_frame_info *frame)
938 if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end) 985 if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end)
939 cie = NULL; 986 cie = NULL;
940 else if (UNW_PC(frame) % state.codeAlign 987 else if (UNW_PC(frame) % state.codeAlign
941 || UNW_SP(frame) % sleb128abs(state.dataAlign)) 988 || UNW_SP(frame) % sleb128abs(state.dataAlign)) {
989 dprintk(1, "Input pointer(s) misaligned (%lx,%lx).",
990 UNW_PC(frame), UNW_SP(frame));
942 return -EPERM; 991 return -EPERM;
943 else { 992 } else {
944 retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end); 993 retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end);
945 /* skip augmentation */ 994 /* skip augmentation */
946 if (((const char *)(cie + 2))[1] == 'z') { 995 if (((const char *)(cie + 2))[1] == 'z') {
@@ -954,6 +1003,8 @@ int unwind(struct unwind_frame_info *frame)
954 || reg_info[retAddrReg].width != sizeof(unsigned long)) 1003 || reg_info[retAddrReg].width != sizeof(unsigned long))
955 cie = NULL; 1004 cie = NULL;
956 } 1005 }
1006 if(!cie)
1007 dprintk(1, "CIE validation failed (%p,%p).", ptr, end);
957 } 1008 }
958 if (cie != NULL) { 1009 if (cie != NULL) {
959 state.cieStart = ptr; 1010 state.cieStart = ptr;
@@ -967,6 +1018,8 @@ int unwind(struct unwind_frame_info *frame)
967 if ((ptr += augSize) > end) 1018 if ((ptr += augSize) > end)
968 fde = NULL; 1019 fde = NULL;
969 } 1020 }
1021 if(!fde)
1022 dprintk(1, "FDE validation failed (%p,%p).", ptr, end);
970 } 1023 }
971 if (cie == NULL || fde == NULL) { 1024 if (cie == NULL || fde == NULL) {
972#ifdef CONFIG_FRAME_POINTER 1025#ifdef CONFIG_FRAME_POINTER
@@ -1025,8 +1078,10 @@ int unwind(struct unwind_frame_info *frame)
1025 || state.cfa.reg >= ARRAY_SIZE(reg_info) 1078 || state.cfa.reg >= ARRAY_SIZE(reg_info)
1026 || reg_info[state.cfa.reg].width != sizeof(unsigned long) 1079 || reg_info[state.cfa.reg].width != sizeof(unsigned long)
1027 || FRAME_REG(state.cfa.reg, unsigned long) % sizeof(unsigned long) 1080 || FRAME_REG(state.cfa.reg, unsigned long) % sizeof(unsigned long)
1028 || state.cfa.offs % sizeof(unsigned long)) 1081 || state.cfa.offs % sizeof(unsigned long)) {
1082 dprintk(1, "Unusable unwind info (%p,%p).", ptr, end);
1029 return -EIO; 1083 return -EIO;
1084 }
1030 /* update frame */ 1085 /* update frame */
1031#ifndef CONFIG_AS_CFI_SIGNAL_FRAME 1086#ifndef CONFIG_AS_CFI_SIGNAL_FRAME
1032 if(frame->call_frame 1087 if(frame->call_frame
@@ -1051,6 +1106,8 @@ int unwind(struct unwind_frame_info *frame)
1051 if (REG_INVALID(i)) { 1106 if (REG_INVALID(i)) {
1052 if (state.regs[i].where == Nowhere) 1107 if (state.regs[i].where == Nowhere)
1053 continue; 1108 continue;
1109 dprintk(1, "Cannot restore register %u (%d).",
1110 i, state.regs[i].where);
1054 return -EIO; 1111 return -EIO;
1055 } 1112 }
1056 switch(state.regs[i].where) { 1113 switch(state.regs[i].where) {
@@ -1059,8 +1116,11 @@ int unwind(struct unwind_frame_info *frame)
1059 case Register: 1116 case Register:
1060 if (state.regs[i].value >= ARRAY_SIZE(reg_info) 1117 if (state.regs[i].value >= ARRAY_SIZE(reg_info)
1061 || REG_INVALID(state.regs[i].value) 1118 || REG_INVALID(state.regs[i].value)
1062 || reg_info[i].width > reg_info[state.regs[i].value].width) 1119 || reg_info[i].width > reg_info[state.regs[i].value].width) {
1120 dprintk(1, "Cannot restore register %u from register %lu.",
1121 i, state.regs[i].value);
1063 return -EIO; 1122 return -EIO;
1123 }
1064 switch(reg_info[state.regs[i].value].width) { 1124 switch(reg_info[state.regs[i].value].width) {
1065#define CASE(n) \ 1125#define CASE(n) \
1066 case sizeof(u##n): \ 1126 case sizeof(u##n): \
@@ -1070,6 +1130,9 @@ int unwind(struct unwind_frame_info *frame)
1070 CASES; 1130 CASES;
1071#undef CASE 1131#undef CASE
1072 default: 1132 default:
1133 dprintk(1, "Unsupported register size %u (%lu).",
1134 reg_info[state.regs[i].value].width,
1135 state.regs[i].value);
1073 return -EIO; 1136 return -EIO;
1074 } 1137 }
1075 break; 1138 break;
@@ -1094,12 +1157,17 @@ int unwind(struct unwind_frame_info *frame)
1094 CASES; 1157 CASES;
1095#undef CASE 1158#undef CASE
1096 default: 1159 default:
1160 dprintk(1, "Unsupported register size %u (%u).",
1161 reg_info[i].width, i);
1097 return -EIO; 1162 return -EIO;
1098 } 1163 }
1099 break; 1164 break;
1100 case Value: 1165 case Value:
1101 if (reg_info[i].width != sizeof(unsigned long)) 1166 if (reg_info[i].width != sizeof(unsigned long)) {
1167 dprintk(1, "Unsupported value size %u (%u).",
1168 reg_info[i].width, i);
1102 return -EIO; 1169 return -EIO;
1170 }
1103 FRAME_REG(i, unsigned long) = cfa + state.regs[i].value 1171 FRAME_REG(i, unsigned long) = cfa + state.regs[i].value
1104 * state.dataAlign; 1172 * state.dataAlign;
1105 break; 1173 break;
@@ -1111,8 +1179,11 @@ int unwind(struct unwind_frame_info *frame)
1111 % sizeof(unsigned long) 1179 % sizeof(unsigned long)
1112 || addr < startLoc 1180 || addr < startLoc
1113 || addr + sizeof(unsigned long) < addr 1181 || addr + sizeof(unsigned long) < addr
1114 || addr + sizeof(unsigned long) > endLoc) 1182 || addr + sizeof(unsigned long) > endLoc) {
1183 dprintk(1, "Bad memory location %lx (%lx).",
1184 addr, state.regs[i].value);
1115 return -EIO; 1185 return -EIO;
1186 }
1116 switch(reg_info[i].width) { 1187 switch(reg_info[i].width) {
1117#define CASE(n) case sizeof(u##n): \ 1188#define CASE(n) case sizeof(u##n): \
1118 probe_kernel_address((u##n *)addr, FRAME_REG(i, u##n)); \ 1189 probe_kernel_address((u##n *)addr, FRAME_REG(i, u##n)); \
@@ -1120,6 +1191,8 @@ int unwind(struct unwind_frame_info *frame)
1120 CASES; 1191 CASES;
1121#undef CASE 1192#undef CASE
1122 default: 1193 default:
1194 dprintk(1, "Unsupported memory size %u (%u).",
1195 reg_info[i].width, i);
1123 return -EIO; 1196 return -EIO;
1124 } 1197 }
1125 } 1198 }
@@ -1128,9 +1201,15 @@ int unwind(struct unwind_frame_info *frame)
1128 } 1201 }
1129 1202
1130 if (UNW_PC(frame) % state.codeAlign 1203 if (UNW_PC(frame) % state.codeAlign
1131 || UNW_SP(frame) % sleb128abs(state.dataAlign) 1204 || UNW_SP(frame) % sleb128abs(state.dataAlign)) {
1132 || (pc == UNW_PC(frame) && sp == UNW_SP(frame))) 1205 dprintk(1, "Output pointer(s) misaligned (%lx,%lx).",
1206 UNW_PC(frame), UNW_SP(frame));
1133 return -EIO; 1207 return -EIO;
1208 }
1209 if (pc == UNW_PC(frame) && sp == UNW_SP(frame)) {
1210 dprintk(1, "No progress (%lx,%lx).", pc, sp);
1211 return -EIO;
1212 }
1134 1213
1135 return 0; 1214 return 0;
1136#undef CASES 1215#undef CASES