diff options
Diffstat (limited to 'src/common/linux/stabs_reader.cc')
-rw-r--r-- | src/common/linux/stabs_reader.cc | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/src/common/linux/stabs_reader.cc b/src/common/linux/stabs_reader.cc index 23b6edbc..67956930 100644 --- a/src/common/linux/stabs_reader.cc +++ b/src/common/linux/stabs_reader.cc @@ -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_++; } |