aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-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