aboutsummaryrefslogtreecommitdiff
path: root/src/common/stabs_reader.cc
diff options
context:
space:
mode:
authorjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-05-05 17:13:42 +0000
committerjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-05-05 17:13:42 +0000
commitdeb500f6c85e4eb65218d171dbdbc528df8ebcfe (patch)
tree0ea47cd891eabf867536fae5a866ca3d5e4a4837 /src/common/stabs_reader.cc
parentBreakpad Linux dumper: Rename DumpStabsHandler to StabsToModule. (diff)
downloadbreakpad-deb500f6c85e4eb65218d171dbdbc528df8ebcfe.tar.xz
Breakpad STABS reader: Properly compute function end addresses.
An N_FUN stabs with no name is an explicit end-of-function marker, whose value is the size of the function. This patch changes the stabs reader to recognize these and use them to compute the function's ending address, instead of treating them as functions with no names and mysterious addresses. It also adds appropriate unit tests. a=jimblandy, r=thestig git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@585 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/stabs_reader.cc')
-rw-r--r--src/common/stabs_reader.cc26
1 files changed, 22 insertions, 4 deletions
diff --git a/src/common/stabs_reader.cc b/src/common/stabs_reader.cc
index add2a8dd..cdad80e7 100644
--- a/src/common/stabs_reader.cc
+++ b/src/common/stabs_reader.cc
@@ -218,13 +218,31 @@ bool StabsReader::ProcessFunction() {
++iterator_;
}
- // If there is a subsequent N_SO or N_FUN entry, its address is our
- // end address.
+ // We've reached the end of the function. See if we can figure out its
+ // ending address.
uint64_t ending_address = 0;
if (!iterator_->at_end) {
assert(iterator_->type == N_SO || iterator_->type == N_FUN);
- ending_address = iterator_->value;
- // Note: we do not advance iterator_ here, since we haven't consumed it.
+ if (iterator_->type == N_FUN) {
+ const char *name = SymbolString();
+ if (name[0] == '\0') {
+ // An N_FUN entry with no name is a terminator for this function;
+ // its value is the function's size.
+ ending_address = function_address + iterator_->value;
+ ++iterator_;
+ } else {
+ // An N_FUN entry with a name is the next function, and we can take
+ // its value as our ending address. Don't advance the iterator, as
+ // we'll use this symbol to start the next function as well.
+ ending_address = iterator_->value;
+ }
+ } else {
+ // An N_SO entry could be an end-of-compilation-unit marker, or the
+ // start of the next compilation unit, but in either case, its value
+ // is our ending address. We don't advance the iterator;
+ // ProcessCompilationUnit will decide what to do with this symbol.
+ ending_address = iterator_->value;
+ }
}
if (! handler_->EndFunction(ending_address))