GNU Binutils with patches for OS216
修订版 | c312754797926d284cd575782d3dc6e1ce14b2ba (tree) |
---|---|
时间 | 2015-02-23 16:44:29 |
作者 | Cary Coutant <ccoutant@goog...> |
Commiter | Cary Coutant |
Improve ODR checking.
2015-02-09 Cary Coutant <ccoutant@google.com>
gold/
* dwarf_reader.cc (Sized_dwarf_line_info::read_lines): Fix debug
output to print correct context.
(Sized_dwarf_line_info::do_addr2line): Add debug output. Return
up to 4 more locations at the beginning of the function.
* symtab.cc (Symbol_table::detect_odr_violations): Get canonical
result before sorting list of line numbers.
@@ -2276,7 +2276,7 @@ Sized_dwarf_line_info<size, big_endian>::read_lines( | ||
2276 | 2276 | "logical %u file %d line %d context %u", |
2277 | 2277 | lsm.shndx, static_cast<int>(lsm.address), |
2278 | 2278 | lsm.line_num, logical.file_num, |
2279 | - logical.line_num, lsm.context); | |
2279 | + logical.line_num, logical.context); | |
2280 | 2280 | entry.offset = static_cast<off_t>(lsm.address); |
2281 | 2281 | entry.header_num = this->current_header_index_; |
2282 | 2282 | entry.file_num = |
@@ -2570,13 +2570,33 @@ Sized_dwarf_line_info<size, big_endian>::do_addr2line( | ||
2570 | 2570 | return ""; |
2571 | 2571 | |
2572 | 2572 | std::string result = this->format_file_lineno(*it); |
2573 | + gold_debug(DEBUG_LOCATION, "do_addr2line: canonical result: %s", | |
2574 | + result.c_str()); | |
2573 | 2575 | if (other_lines != NULL) |
2574 | - for (++it; it != offsets->end() && it->offset == offset; ++it) | |
2575 | - { | |
2576 | - if (it->line_num == -1) | |
2577 | - continue; // The end of a previous function. | |
2578 | - other_lines->push_back(this->format_file_lineno(*it)); | |
2579 | - } | |
2576 | + { | |
2577 | + unsigned int last_file_num = it->file_num; | |
2578 | + int last_line_num = it->line_num; | |
2579 | + // Return up to 4 more locations from the beginning of the function | |
2580 | + // for fuzzy matching. | |
2581 | + for (++it; it != offsets->end(); ++it) | |
2582 | + { | |
2583 | + if (it->offset == offset && it->line_num == -1) | |
2584 | + continue; // The end of a previous function. | |
2585 | + if (it->line_num == -1) | |
2586 | + break; // The end of the current function. | |
2587 | + if (it->file_num != last_file_num || it->line_num != last_line_num) | |
2588 | + { | |
2589 | + other_lines->push_back(this->format_file_lineno(*it)); | |
2590 | + gold_debug(DEBUG_LOCATION, "do_addr2line: other: %s", | |
2591 | + other_lines->back().c_str()); | |
2592 | + last_file_num = it->file_num; | |
2593 | + last_line_num = it->line_num; | |
2594 | + } | |
2595 | + if (it->offset > offset && other_lines->size() >= 4) | |
2596 | + break; | |
2597 | + } | |
2598 | + } | |
2599 | + | |
2580 | 2600 | return result; |
2581 | 2601 | } |
2582 | 2602 |
@@ -3336,8 +3336,11 @@ Symbol_table::detect_odr_violations(const Task* task, | ||
3336 | 3336 | first_object_name = locs->object->name(); |
3337 | 3337 | first_object_linenos = this->linenos_from_loc(task, *locs); |
3338 | 3338 | } |
3339 | + if (first_object_linenos.empty()) | |
3340 | + continue; | |
3339 | 3341 | |
3340 | 3342 | // Sort by Odr_violation_compare to make std::set_intersection work. |
3343 | + std::string first_object_canonical_result = first_object_linenos.back(); | |
3341 | 3344 | std::sort(first_object_linenos.begin(), first_object_linenos.end(), |
3342 | 3345 | Odr_violation_compare()); |
3343 | 3346 |
@@ -3349,6 +3352,8 @@ Symbol_table::detect_odr_violations(const Task* task, | ||
3349 | 3352 | if (linenos.empty()) |
3350 | 3353 | continue; |
3351 | 3354 | // Sort by Odr_violation_compare to make std::set_intersection work. |
3355 | + gold_assert(!linenos.empty()); | |
3356 | + std::string second_object_canonical_result = linenos.back(); | |
3352 | 3357 | std::sort(linenos.begin(), linenos.end(), Odr_violation_compare()); |
3353 | 3358 | |
3354 | 3359 | Check_intersection intersection_result = |
@@ -3367,13 +3372,11 @@ Symbol_table::detect_odr_violations(const Task* task, | ||
3367 | 3372 | // which may not be the location we expect to intersect |
3368 | 3373 | // with another definition. We could print the whole |
3369 | 3374 | // set of locations, but that seems too verbose. |
3370 | - gold_assert(!first_object_linenos.empty()); | |
3371 | - gold_assert(!linenos.empty()); | |
3372 | 3375 | fprintf(stderr, _(" %s from %s\n"), |
3373 | - first_object_linenos[0].c_str(), | |
3376 | + first_object_canonical_result.c_str(), | |
3374 | 3377 | first_object_name.c_str()); |
3375 | 3378 | fprintf(stderr, _(" %s from %s\n"), |
3376 | - linenos[0].c_str(), | |
3379 | + second_object_canonical_result.c_str(), | |
3377 | 3380 | locs->object->name().c_str()); |
3378 | 3381 | // Only print one broken pair, to avoid needing to |
3379 | 3382 | // compare against a list of the disjoint definition |