mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-01-01 20:24:40 +01:00
Breakpad Linux dumper: STABS reader incorrectly assumes a single compilation unit
The stabs reading code in google-breakpad incorrectly assumes that the stabs data is a single compilation unit. Specifically, it ignores N_UNDF stabs and assumes that all string indices are relative to the beginning of the .stabstr section. This is true when linking with the GNU linker by default, because the GNU linker optimizes stabs debug info. The gold linker does not do this optimization. It can be disabled when using the GNU linker with the --traditional-format command line option. For more details of the problem, see: http://sourceware.org/bugzilla/show_bug.cgi?id=10338 http://code.google.com/p/google-breakpad/issues/detail?id=359 This patch adds unit tests that reproduce the failure, and fixes the stabs parser. a=jimblandy, r=nealsid git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@490 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
7b873221e6
commit
5251e64f48
3 changed files with 194 additions and 35 deletions
|
|
@ -43,6 +43,8 @@ StabsReader::StabsReader(const uint8_t *stab, size_t stab_size,
|
|||
stabstr_(stabstr),
|
||||
stabstr_size_(stabstr_size),
|
||||
handler_(handler),
|
||||
string_offset_(0),
|
||||
next_cu_string_offset_(0),
|
||||
symbol_(NULL),
|
||||
current_source_file_(NULL) {
|
||||
symbols_ = reinterpret_cast<const struct nlist *>(stab);
|
||||
|
|
@ -50,7 +52,7 @@ StabsReader::StabsReader(const uint8_t *stab, size_t stab_size,
|
|||
}
|
||||
|
||||
const char *StabsReader::SymbolString() {
|
||||
ptrdiff_t offset = symbol_->n_un.n_strx;
|
||||
ptrdiff_t offset = string_offset_ + symbol_->n_un.n_strx;
|
||||
if (offset < 0 || (size_t) offset >= stabstr_size_) {
|
||||
handler_->Warning("symbol %d: name offset outside the string section",
|
||||
symbol_ - symbols_);
|
||||
|
|
@ -67,6 +69,21 @@ bool StabsReader::Process() {
|
|||
if (symbol_->n_type == N_SO) {
|
||||
if (! ProcessCompilationUnit())
|
||||
return false;
|
||||
} else if (symbol_->n_type == N_UNDF) {
|
||||
// At the head of each compilation unit's entries there is an
|
||||
// N_UNDF stab giving the number of symbols in the compilation
|
||||
// unit, and the number of bytes that compilation unit's strings
|
||||
// take up in the .stabstr section. Each CU's strings are
|
||||
// separate; the n_strx values are offsets within the current
|
||||
// CU's portion of the .stabstr section.
|
||||
//
|
||||
// As an optimization, the GNU linker combines all the
|
||||
// compilation units into one, with a single N_UNDF at the
|
||||
// beginning. However, other linkers, like Gold, do not perform
|
||||
// this optimization.
|
||||
string_offset_ = next_cu_string_offset_;
|
||||
next_cu_string_offset_ = SymbolValue();
|
||||
symbol_++;
|
||||
} else
|
||||
symbol_++;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue