| 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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 // RetrieveNearestRange instead of RetrieveRange so that, if there | 196 // RetrieveNearestRange instead of RetrieveRange so that, if there |
| 197 // is no such function, we can use the next function to bound the | 197 // is no such function, we can use the next function to bound the |
| 198 // extent of the PUBLIC symbol we find, below. This does mean we | 198 // extent of the PUBLIC symbol we find, below. This does mean we |
| 199 // need to check that address indeed falls within the function we | 199 // need to check that address indeed falls within the function we |
| 200 // find; do the range comparison in an overflow-friendly way. | 200 // find; do the range comparison in an overflow-friendly way. |
| 201 linked_ptr<Function> func; | 201 linked_ptr<Function> func; |
| 202 linked_ptr<PublicSymbol> public_symbol; | 202 linked_ptr<PublicSymbol> public_symbol; |
| 203 MemAddr function_base; | 203 MemAddr function_base; |
| 204 MemAddr function_size; | 204 MemAddr function_size; |
| 205 MemAddr public_address; | 205 MemAddr public_address; |
| 206 if (functions_.RetrieveNearestRange(address, &func, | 206 if (functions_.RetrieveNearestRange(address, &func, &function_base, |
| 207 &function_base, &function_size) && | 207 NULL /* delta */, &function_size) && |
| 208 address >= function_base && address - function_base < function_size) { | 208 address >= function_base && address - function_base < function_size) { |
| 209 frame->function_name = func->name; | 209 frame->function_name = func->name; |
| 210 frame->function_base = frame->module->base_address() + function_base; | 210 frame->function_base = frame->module->base_address() + function_base; |
| 211 | 211 |
| 212 linked_ptr<Line> line; | 212 linked_ptr<Line> line; |
| 213 MemAddr line_base; | 213 MemAddr line_base; |
| 214 if (func->lines.RetrieveRange(address, &line, &line_base, NULL)) { | 214 if (func->lines.RetrieveRange(address, &line, &line_base, NULL /* delta */, |
| 215 NULL /* size */)) { |
| 215 FileMap::const_iterator it = files_.find(line->source_file_id); | 216 FileMap::const_iterator it = files_.find(line->source_file_id); |
| 216 if (it != files_.end()) { | 217 if (it != files_.end()) { |
| 217 frame->source_file_name = files_.find(line->source_file_id)->second; | 218 frame->source_file_name = files_.find(line->source_file_id)->second; |
| 218 } | 219 } |
| 219 frame->source_line = line->line; | 220 frame->source_line = line->line; |
| 220 frame->source_line_base = frame->module->base_address() + line_base; | 221 frame->source_line_base = frame->module->base_address() + line_base; |
| 221 } | 222 } |
| 222 } else if (public_symbols_.Retrieve(address, | 223 } else if (public_symbols_.Retrieve(address, |
| 223 &public_symbol, &public_address) && | 224 &public_symbol, &public_address) && |
| 224 (!func.get() || public_address > function_base)) { | 225 (!func.get() || public_address > function_base)) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 249 | 250 |
| 250 // Even without a relevant STACK line, many functions contain | 251 // Even without a relevant STACK line, many functions contain |
| 251 // information about how much space their parameters consume on the | 252 // information about how much space their parameters consume on the |
| 252 // stack. Use RetrieveNearestRange instead of RetrieveRange, so that | 253 // stack. Use RetrieveNearestRange instead of RetrieveRange, so that |
| 253 // we can use the function to bound the extent of the PUBLIC symbol, | 254 // we can use the function to bound the extent of the PUBLIC symbol, |
| 254 // below. However, this does mean we need to check that ADDRESS | 255 // below. However, this does mean we need to check that ADDRESS |
| 255 // falls within the retrieved function's range; do the range | 256 // falls within the retrieved function's range; do the range |
| 256 // comparison in an overflow-friendly way. | 257 // comparison in an overflow-friendly way. |
| 257 linked_ptr<Function> function; | 258 linked_ptr<Function> function; |
| 258 MemAddr function_base, function_size; | 259 MemAddr function_base, function_size; |
| 259 if (functions_.RetrieveNearestRange(address, &function, | 260 if (functions_.RetrieveNearestRange(address, &function, &function_base, |
| 260 &function_base, &function_size) && | 261 NULL /* delta */, &function_size) && |
| 261 address >= function_base && address - function_base < function_size) { | 262 address >= function_base && address - function_base < function_size) { |
| 262 result->parameter_size = function->parameter_size; | 263 result->parameter_size = function->parameter_size; |
| 263 result->valid |= WindowsFrameInfo::VALID_PARAMETER_SIZE; | 264 result->valid |= WindowsFrameInfo::VALID_PARAMETER_SIZE; |
| 264 return result.release(); | 265 return result.release(); |
| 265 } | 266 } |
| 266 | 267 |
| 267 // PUBLIC symbols might have a parameter size. Use the function we | 268 // PUBLIC symbols might have a parameter size. Use the function we |
| 268 // found above to limit the range the public symbol covers. | 269 // found above to limit the range the public symbol covers. |
| 269 linked_ptr<PublicSymbol> public_symbol; | 270 linked_ptr<PublicSymbol> public_symbol; |
| 270 MemAddr public_address; | 271 MemAddr public_address; |
| 271 if (public_symbols_.Retrieve(address, &public_symbol, &public_address) && | 272 if (public_symbols_.Retrieve(address, &public_symbol, &public_address) && |
| 272 (!function.get() || public_address > function_base)) { | 273 (!function.get() || public_address > function_base)) { |
| 273 result->parameter_size = public_symbol->parameter_size; | 274 result->parameter_size = public_symbol->parameter_size; |
| 274 } | 275 } |
| 275 | 276 |
| 276 return NULL; | 277 return NULL; |
| 277 } | 278 } |
| 278 | 279 |
| 279 CFIFrameInfo *BasicSourceLineResolver::Module::FindCFIFrameInfo( | 280 CFIFrameInfo *BasicSourceLineResolver::Module::FindCFIFrameInfo( |
| 280 const StackFrame *frame) const { | 281 const StackFrame *frame) const { |
| 281 MemAddr address = frame->instruction - frame->module->base_address(); | 282 MemAddr address = frame->instruction - frame->module->base_address(); |
| 282 MemAddr initial_base, initial_size; | 283 MemAddr initial_base, initial_size; |
| 283 string initial_rules; | 284 string initial_rules; |
| 284 | 285 |
| 285 // Find the initial rule whose range covers this address. That | 286 // Find the initial rule whose range covers this address. That |
| 286 // provides an initial set of register recovery rules. Then, walk | 287 // provides an initial set of register recovery rules. Then, walk |
| 287 // forward from the initial rule's starting address to frame's | 288 // forward from the initial rule's starting address to frame's |
| 288 // instruction address, applying delta rules. | 289 // instruction address, applying delta rules. |
| 289 if (!cfi_initial_rules_.RetrieveRange(address, &initial_rules, | 290 if (!cfi_initial_rules_.RetrieveRange(address, &initial_rules, &initial_base, |
| 290 &initial_base, &initial_size)) { | 291 NULL /* delta */, &initial_size)) { |
| 291 return NULL; | 292 return NULL; |
| 292 } | 293 } |
| 293 | 294 |
| 294 // Create a frame info structure, and populate it with the rules from | 295 // Create a frame info structure, and populate it with the rules from |
| 295 // the STACK CFI INIT record. | 296 // the STACK CFI INIT record. |
| 296 scoped_ptr<CFIFrameInfo> rules(new CFIFrameInfo()); | 297 scoped_ptr<CFIFrameInfo> rules(new CFIFrameInfo()); |
| 297 if (!ParseCFIRuleSet(initial_rules, rules.get())) | 298 if (!ParseCFIRuleSet(initial_rules, rules.get())) |
| 298 return NULL; | 299 return NULL; |
| 299 | 300 |
| 300 // Find the first delta rule that falls within the initial rule's range. | 301 // Find the first delta rule that falls within the initial rule's range. |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 if (!IsValidAfterNumber(after_number) || | 589 if (!IsValidAfterNumber(after_number) || |
| 589 *address == std::numeric_limits<unsigned long long>::max()) { | 590 *address == std::numeric_limits<unsigned long long>::max()) { |
| 590 return false; | 591 return false; |
| 591 } | 592 } |
| 592 *stack_param_size = strtol(tokens[1], &after_number, 16); | 593 *stack_param_size = strtol(tokens[1], &after_number, 16); |
| 593 if (!IsValidAfterNumber(after_number) || | 594 if (!IsValidAfterNumber(after_number) || |
| 594 *stack_param_size == std::numeric_limits<long>::max() || | 595 *stack_param_size == std::numeric_limits<long>::max() || |
| 595 *stack_param_size < 0) { | 596 *stack_param_size < 0) { |
| 596 return false; | 597 return false; |
| 597 } | 598 } |
| 598 *name = tokens[2]; | 599 *name = tokens[2]; |
| 599 | 600 |
| 600 return true; | 601 return true; |
| 601 } | 602 } |
| 602 | 603 |
| 603 // static | 604 // static |
| 604 bool SymbolParseHelper::IsValidAfterNumber(char *after_number) { | 605 bool SymbolParseHelper::IsValidAfterNumber(char *after_number) { |
| 605 if (after_number != NULL && strchr(kWhitespace, *after_number) != NULL) { | 606 if (after_number != NULL && strchr(kWhitespace, *after_number) != NULL) { |
| 606 return true; | 607 return true; |
| 607 } | 608 } |
| 608 return false; | 609 return false; |
| 609 } | 610 } |
| 610 | 611 |
| 611 } // namespace google_breakpad | 612 } // namespace google_breakpad |
| OLD | NEW |