diff options
author | Ian Lance Taylor <ian@airs.com> | 2011-03-10 01:31:33 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2011-03-10 01:31:33 +0000 |
commit | 71ff89863ff23a581a1578755785e6b39dd209f2 (patch) | |
tree | b5aab2587b661dc64d6117602ecb030274857c93 /gold/dwarf_reader.h | |
parent | a19fefdc57f5eafcb682175f2b2bcd8f6f366c90 (diff) | |
download | gdb-71ff89863ff23a581a1578755785e6b39dd209f2.zip gdb-71ff89863ff23a581a1578755785e6b39dd209f2.tar.gz gdb-71ff89863ff23a581a1578755785e6b39dd209f2.tar.bz2 |
* 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.
Diffstat (limited to 'gold/dwarf_reader.h')
-rw-r--r-- | gold/dwarf_reader.h | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/gold/dwarf_reader.h b/gold/dwarf_reader.h index 8fe7898..3f92dd3 100644 --- a/gold/dwarf_reader.h +++ b/gold/dwarf_reader.h @@ -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 - - // 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. + // 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; + + // 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 |