forked from Imagelibrary/binutils-gdb
* dwarf_reader.cc (Sized_dwarf_line_info): Include all lines,
but mark earlier ones as non-canonical (offset_to_iterator): Update search target and example (do_addr2line): Return extra lines in a vector* (format_file_lineno): Extract from do_addr2line (one_addr2line): Add vector* out-param * dwarf_reader.h (Offset_to_lineno_entry): New field recording when a lineno entry appeared last for its instruction (Dwarf_line_info): Add vector* out-param * object.cc (Relocate_info): Pass NULL for the vector* out-param * symtab.cc (Odr_violation_compare): Include the lineno in the comparison again. (linenos_from_loc): New. Combine the canonical line for an address with its other lines. (True_if_intersect): New. Helper functor to make std::set_intersection a query. (detect_odr_violations): Compare sets of lines instead of just one line for each function. This became less deterministic, but has fewer false positives. * symtab.h: Declarations. * testsuite/Makefile.am (odr_violation2.o): Compile with -O2 to mix an optimized and non-optimized object in the same binary (odr_violation2.so): Same. * testsuite/Makefile.in: Regenerate from Makefile.am. * testsuite/debug_msg.cc (main): Make OdrDerived classes. * testsuite/debug_msg.sh: Update line numbers and add assertions. * testsuite/odr_violation1.cc: Use OdrDerived, in a non-optimized context. * testsuite/odr_violation2.cc: Make sure Ordering::operator() isn't inlined, and use OdrDerived in an optimized context. * testsuite/odr_header1.h: Defines OdrDerived, where optimization will change the first-instruction-in-the-destructor's file and line number. * testsuite/odr_header2.h: Defines OdrBase.
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <limits.h>
|
||||
|
||||
#include "elfcpp.h"
|
||||
#include "elfcpp_swap.h"
|
||||
@@ -44,14 +45,25 @@ struct Offset_to_lineno_entry
|
||||
{
|
||||
off_t offset;
|
||||
int header_num; // which file-list to use (i.e. which .o file are we in)
|
||||
int file_num; // a pointer into files_
|
||||
int line_num; // the line number in the source file
|
||||
// A pointer into files_.
|
||||
unsigned int file_num : sizeof(int) * CHAR_BIT - 1;
|
||||
// True if this was the last entry for the current offset, meaning
|
||||
// it's the line that actually applies.
|
||||
unsigned int last_line_for_offset : 1;
|
||||
// The line number in the source file. -1 to indicate end-of-function.
|
||||
int line_num;
|
||||
|
||||
// When we add entries to the table, we always use the last entry
|
||||
// with a given offset. Given proper DWARF info, this should ensure
|
||||
// that the offset is a sufficient sort key.
|
||||
// This sorts by offsets first, and then puts the correct line to
|
||||
// report for a given offset at the beginning of the run of equal
|
||||
// offsets (so that asking for 1 line gives the best answer). This
|
||||
// is not a total ordering.
|
||||
bool operator<(const Offset_to_lineno_entry& that) const
|
||||
{ return this->offset < that.offset; }
|
||||
{
|
||||
if (this->offset != that.offset)
|
||||
return this->offset < that.offset;
|
||||
// Note the '>' which makes this sort 'true' first.
|
||||
return this->last_line_for_offset > that.last_line_for_offset;
|
||||
}
|
||||
};
|
||||
|
||||
// This class is used to read the line information from the debugging
|
||||
@@ -70,10 +82,13 @@ class Dwarf_line_info
|
||||
// Given a section number and an offset, returns the associated
|
||||
// file and line-number, as a string: "file:lineno". If unable
|
||||
// to do the mapping, returns the empty string. You must call
|
||||
// read_line_mappings() before calling this function.
|
||||
// read_line_mappings() before calling this function. If
|
||||
// 'other_lines' is non-NULL, fills that in with other line
|
||||
// numbers assigned to the same offset.
|
||||
std::string
|
||||
addr2line(unsigned int shndx, off_t offset)
|
||||
{ return do_addr2line(shndx, offset); }
|
||||
addr2line(unsigned int shndx, off_t offset,
|
||||
std::vector<std::string>* other_lines)
|
||||
{ return this->do_addr2line(shndx, offset, other_lines); }
|
||||
|
||||
// A helper function for a single addr2line lookup. It also keeps a
|
||||
// cache of the last CACHE_SIZE Dwarf_line_info objects it created;
|
||||
@@ -83,7 +98,7 @@ class Dwarf_line_info
|
||||
// NOTE: Not thread-safe, so only call from one thread at a time.
|
||||
static std::string
|
||||
one_addr2line(Object* object, unsigned int shndx, off_t offset,
|
||||
size_t cache_size);
|
||||
size_t cache_size, std::vector<std::string>* other_lines);
|
||||
|
||||
// This reclaims all the memory that one_addr2line may have cached.
|
||||
// Use this when you know you will not be calling one_addr2line again.
|
||||
@@ -92,7 +107,8 @@ class Dwarf_line_info
|
||||
|
||||
private:
|
||||
virtual std::string
|
||||
do_addr2line(unsigned int shndx, off_t offset) = 0;
|
||||
do_addr2line(unsigned int shndx, off_t offset,
|
||||
std::vector<std::string>* other_lines) = 0;
|
||||
};
|
||||
|
||||
template<int size, bool big_endian>
|
||||
@@ -106,7 +122,12 @@ class Sized_dwarf_line_info : public Dwarf_line_info
|
||||
|
||||
private:
|
||||
std::string
|
||||
do_addr2line(unsigned int shndx, off_t offset);
|
||||
do_addr2line(unsigned int shndx, off_t offset,
|
||||
std::vector<std::string>* other_lines);
|
||||
|
||||
// Formats a file and line number to a string like "dirname/filename:lineno".
|
||||
std::string
|
||||
format_file_lineno(const Offset_to_lineno_entry& lineno) const;
|
||||
|
||||
// Start processing line info, and populates the offset_map_.
|
||||
// If SHNDX is non-negative, only store debug information that
|
||||
|
||||
Reference in New Issue
Block a user