OLD | NEW |
1 // Copyright (c) 2010 Google Inc. | 1 // Copyright (c) 2010 Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 | 83 |
84 static const char* register_names[] = { | 84 static const char* register_names[] = { |
85 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", | 85 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", |
86 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", | 86 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", |
87 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", | 87 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", |
88 "fps", "cpsr", | 88 "fps", "cpsr", |
89 NULL | 89 NULL |
90 }; | 90 }; |
91 | 91 |
92 // Populate a dictionary with the valid register values in last_frame. | 92 // Populate a dictionary with the valid register values in last_frame. |
93 CFIFrameInfo::RegisterValueMap<u_int32_t> callee_registers; | 93 CFIFrameInfo::RegisterValueMap<uint32_t> callee_registers; |
94 for (int i = 0; register_names[i]; i++) | 94 for (int i = 0; register_names[i]; i++) |
95 if (last_frame->context_validity & StackFrameARM::RegisterValidFlag(i)) | 95 if (last_frame->context_validity & StackFrameARM::RegisterValidFlag(i)) |
96 callee_registers[register_names[i]] = last_frame->context.iregs[i]; | 96 callee_registers[register_names[i]] = last_frame->context.iregs[i]; |
97 | 97 |
98 // Use the STACK CFI data to recover the caller's register values. | 98 // Use the STACK CFI data to recover the caller's register values. |
99 CFIFrameInfo::RegisterValueMap<u_int32_t> caller_registers; | 99 CFIFrameInfo::RegisterValueMap<uint32_t> caller_registers; |
100 if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, | 100 if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, |
101 &caller_registers)) | 101 &caller_registers)) |
102 return NULL; | 102 return NULL; |
103 | 103 |
104 // Construct a new stack frame given the values the CFI recovered. | 104 // Construct a new stack frame given the values the CFI recovered. |
105 scoped_ptr<StackFrameARM> frame(new StackFrameARM()); | 105 scoped_ptr<StackFrameARM> frame(new StackFrameARM()); |
106 for (int i = 0; register_names[i]; i++) { | 106 for (int i = 0; register_names[i]; i++) { |
107 CFIFrameInfo::RegisterValueMap<u_int32_t>::iterator entry = | 107 CFIFrameInfo::RegisterValueMap<uint32_t>::iterator entry = |
108 caller_registers.find(register_names[i]); | 108 caller_registers.find(register_names[i]); |
109 if (entry != caller_registers.end()) { | 109 if (entry != caller_registers.end()) { |
110 // We recovered the value of this register; fill the context with the | 110 // We recovered the value of this register; fill the context with the |
111 // value from caller_registers. | 111 // value from caller_registers. |
112 frame->context_validity |= StackFrameARM::RegisterValidFlag(i); | 112 frame->context_validity |= StackFrameARM::RegisterValidFlag(i); |
113 frame->context.iregs[i] = entry->second; | 113 frame->context.iregs[i] = entry->second; |
114 } else if (4 <= i && i <= 11 && (last_frame->context_validity & | 114 } else if (4 <= i && i <= 11 && (last_frame->context_validity & |
115 StackFrameARM::RegisterValidFlag(i))) { | 115 StackFrameARM::RegisterValidFlag(i))) { |
116 // If the STACK CFI data doesn't mention some callee-saves register, and | 116 // If the STACK CFI data doesn't mention some callee-saves register, and |
117 // it is valid in the callee, assume the callee has not yet changed it. | 117 // it is valid in the callee, assume the callee has not yet changed it. |
118 // Registers r4 through r11 are callee-saves, according to the Procedure | 118 // Registers r4 through r11 are callee-saves, according to the Procedure |
119 // Call Standard for the ARM Architecture, which the Linux ABI follows. | 119 // Call Standard for the ARM Architecture, which the Linux ABI follows. |
120 frame->context_validity |= StackFrameARM::RegisterValidFlag(i); | 120 frame->context_validity |= StackFrameARM::RegisterValidFlag(i); |
121 frame->context.iregs[i] = last_frame->context.iregs[i]; | 121 frame->context.iregs[i] = last_frame->context.iregs[i]; |
122 } | 122 } |
123 } | 123 } |
124 // If the CFI doesn't recover the PC explicitly, then use .ra. | 124 // If the CFI doesn't recover the PC explicitly, then use .ra. |
125 if (!(frame->context_validity & StackFrameARM::CONTEXT_VALID_PC)) { | 125 if (!(frame->context_validity & StackFrameARM::CONTEXT_VALID_PC)) { |
126 CFIFrameInfo::RegisterValueMap<u_int32_t>::iterator entry = | 126 CFIFrameInfo::RegisterValueMap<uint32_t>::iterator entry = |
127 caller_registers.find(".ra"); | 127 caller_registers.find(".ra"); |
128 if (entry != caller_registers.end()) { | 128 if (entry != caller_registers.end()) { |
129 if (fp_register_ == -1) { | 129 if (fp_register_ == -1) { |
130 frame->context_validity |= StackFrameARM::CONTEXT_VALID_PC; | 130 frame->context_validity |= StackFrameARM::CONTEXT_VALID_PC; |
131 frame->context.iregs[MD_CONTEXT_ARM_REG_PC] = entry->second; | 131 frame->context.iregs[MD_CONTEXT_ARM_REG_PC] = entry->second; |
132 } else { | 132 } else { |
133 // The CFI updated the link register and not the program counter. | 133 // The CFI updated the link register and not the program counter. |
134 // Handle getting the program counter from the link register. | 134 // Handle getting the program counter from the link register. |
135 frame->context_validity |= StackFrameARM::CONTEXT_VALID_PC; | 135 frame->context_validity |= StackFrameARM::CONTEXT_VALID_PC; |
136 frame->context_validity |= StackFrameARM::CONTEXT_VALID_LR; | 136 frame->context_validity |= StackFrameARM::CONTEXT_VALID_LR; |
137 frame->context.iregs[MD_CONTEXT_ARM_REG_LR] = entry->second; | 137 frame->context.iregs[MD_CONTEXT_ARM_REG_LR] = entry->second; |
138 frame->context.iregs[MD_CONTEXT_ARM_REG_PC] = | 138 frame->context.iregs[MD_CONTEXT_ARM_REG_PC] = |
139 last_frame->context.iregs[MD_CONTEXT_ARM_REG_LR]; | 139 last_frame->context.iregs[MD_CONTEXT_ARM_REG_LR]; |
140 } | 140 } |
141 } | 141 } |
142 } | 142 } |
143 // If the CFI doesn't recover the SP explicitly, then use .cfa. | 143 // If the CFI doesn't recover the SP explicitly, then use .cfa. |
144 if (!(frame->context_validity & StackFrameARM::CONTEXT_VALID_SP)) { | 144 if (!(frame->context_validity & StackFrameARM::CONTEXT_VALID_SP)) { |
145 CFIFrameInfo::RegisterValueMap<u_int32_t>::iterator entry = | 145 CFIFrameInfo::RegisterValueMap<uint32_t>::iterator entry = |
146 caller_registers.find(".cfa"); | 146 caller_registers.find(".cfa"); |
147 if (entry != caller_registers.end()) { | 147 if (entry != caller_registers.end()) { |
148 frame->context_validity |= StackFrameARM::CONTEXT_VALID_SP; | 148 frame->context_validity |= StackFrameARM::CONTEXT_VALID_SP; |
149 frame->context.iregs[MD_CONTEXT_ARM_REG_SP] = entry->second; | 149 frame->context.iregs[MD_CONTEXT_ARM_REG_SP] = entry->second; |
150 } | 150 } |
151 } | 151 } |
152 | 152 |
153 // If we didn't recover the PC and the SP, then the frame isn't very useful. | 153 // If we didn't recover the PC and the SP, then the frame isn't very useful. |
154 static const int essentials = (StackFrameARM::CONTEXT_VALID_SP | 154 static const int essentials = (StackFrameARM::CONTEXT_VALID_SP |
155 | StackFrameARM::CONTEXT_VALID_PC); | 155 | StackFrameARM::CONTEXT_VALID_PC); |
156 if ((frame->context_validity & essentials) != essentials) | 156 if ((frame->context_validity & essentials) != essentials) |
157 return NULL; | 157 return NULL; |
158 | 158 |
159 frame->trust = StackFrame::FRAME_TRUST_CFI; | 159 frame->trust = StackFrame::FRAME_TRUST_CFI; |
160 return frame.release(); | 160 return frame.release(); |
161 } | 161 } |
162 | 162 |
163 StackFrameARM* StackwalkerARM::GetCallerByStackScan( | 163 StackFrameARM* StackwalkerARM::GetCallerByStackScan( |
164 const vector<StackFrame*> &frames) { | 164 const vector<StackFrame*> &frames) { |
165 StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back()); | 165 StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back()); |
166 u_int32_t last_sp = last_frame->context.iregs[MD_CONTEXT_ARM_REG_SP]; | 166 uint32_t last_sp = last_frame->context.iregs[MD_CONTEXT_ARM_REG_SP]; |
167 u_int32_t caller_sp, caller_pc; | 167 uint32_t caller_sp, caller_pc; |
168 | 168 |
169 // When searching for the caller of the context frame, | 169 // When searching for the caller of the context frame, |
170 // allow the scanner to look farther down the stack. | 170 // allow the scanner to look farther down the stack. |
171 const int kRASearchWords = frames.size() == 1 ? | 171 const int kRASearchWords = frames.size() == 1 ? |
172 Stackwalker::kRASearchWords * 4 : | 172 Stackwalker::kRASearchWords * 4 : |
173 Stackwalker::kRASearchWords; | 173 Stackwalker::kRASearchWords; |
174 | 174 |
175 if (!ScanForReturnAddress(last_sp, &caller_sp, &caller_pc, | 175 if (!ScanForReturnAddress(last_sp, &caller_sp, &caller_pc, |
176 kRASearchWords)) { | 176 kRASearchWords)) { |
177 // No plausible return address was found. | 177 // No plausible return address was found. |
(...skipping 21 matching lines...) Expand all Loading... |
199 | 199 |
200 StackFrameARM* StackwalkerARM::GetCallerByFramePointer( | 200 StackFrameARM* StackwalkerARM::GetCallerByFramePointer( |
201 const vector<StackFrame*> &frames) { | 201 const vector<StackFrame*> &frames) { |
202 StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back()); | 202 StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back()); |
203 | 203 |
204 if (!(last_frame->context_validity & | 204 if (!(last_frame->context_validity & |
205 StackFrameARM::RegisterValidFlag(fp_register_))) { | 205 StackFrameARM::RegisterValidFlag(fp_register_))) { |
206 return NULL; | 206 return NULL; |
207 } | 207 } |
208 | 208 |
209 u_int32_t last_fp = last_frame->context.iregs[fp_register_]; | 209 uint32_t last_fp = last_frame->context.iregs[fp_register_]; |
210 | 210 |
211 u_int32_t caller_fp = 0; | 211 uint32_t caller_fp = 0; |
212 if (last_fp && !memory_->GetMemoryAtAddress(last_fp, &caller_fp)) { | 212 if (last_fp && !memory_->GetMemoryAtAddress(last_fp, &caller_fp)) { |
213 BPLOG(ERROR) << "Unable to read caller_fp from last_fp: 0x" | 213 BPLOG(ERROR) << "Unable to read caller_fp from last_fp: 0x" |
214 << std::hex << last_fp; | 214 << std::hex << last_fp; |
215 return NULL; | 215 return NULL; |
216 } | 216 } |
217 | 217 |
218 u_int32_t caller_lr = 0; | 218 uint32_t caller_lr = 0; |
219 if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 4, &caller_lr)) { | 219 if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 4, &caller_lr)) { |
220 BPLOG(ERROR) << "Unable to read caller_lr from last_fp + 4: 0x" | 220 BPLOG(ERROR) << "Unable to read caller_lr from last_fp + 4: 0x" |
221 << std::hex << (last_fp + 4); | 221 << std::hex << (last_fp + 4); |
222 return NULL; | 222 return NULL; |
223 } | 223 } |
224 | 224 |
225 u_int32_t caller_sp = last_fp ? last_fp + 8 : | 225 uint32_t caller_sp = last_fp ? last_fp + 8 : |
226 last_frame->context.iregs[MD_CONTEXT_ARM_REG_SP]; | 226 last_frame->context.iregs[MD_CONTEXT_ARM_REG_SP]; |
227 | 227 |
228 // Create a new stack frame (ownership will be transferred to the caller) | 228 // Create a new stack frame (ownership will be transferred to the caller) |
229 // and fill it in. | 229 // and fill it in. |
230 StackFrameARM* frame = new StackFrameARM(); | 230 StackFrameARM* frame = new StackFrameARM(); |
231 | 231 |
232 frame->trust = StackFrame::FRAME_TRUST_FP; | 232 frame->trust = StackFrame::FRAME_TRUST_FP; |
233 frame->context = last_frame->context; | 233 frame->context = last_frame->context; |
234 frame->context.iregs[fp_register_] = caller_fp; | 234 frame->context.iregs[fp_register_] = caller_fp; |
235 frame->context.iregs[MD_CONTEXT_ARM_REG_SP] = caller_sp; | 235 frame->context.iregs[MD_CONTEXT_ARM_REG_SP] = caller_sp; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 // match up with the line that contains the function call. Callers that | 292 // match up with the line that contains the function call. Callers that |
293 // require the exact return address value may access | 293 // require the exact return address value may access |
294 // frame->context.iregs[MD_CONTEXT_ARM_REG_PC]. | 294 // frame->context.iregs[MD_CONTEXT_ARM_REG_PC]. |
295 frame->instruction = frame->context.iregs[MD_CONTEXT_ARM_REG_PC] - 2; | 295 frame->instruction = frame->context.iregs[MD_CONTEXT_ARM_REG_PC] - 2; |
296 | 296 |
297 return frame.release(); | 297 return frame.release(); |
298 } | 298 } |
299 | 299 |
300 | 300 |
301 } // namespace google_breakpad | 301 } // namespace google_breakpad |
OLD | NEW |