Linux dumper: Don't switch to wrong source file when starting new function.

In STABS, if one function's line number information contains an N_SOL
entry to switch to a new source file, then the next function's line
data should pick up in the same source file where the prior function
left off.  However, the Linux dumper restarts each function in the
compilation unit's main source file.  This patch fixes that, so that
the output attributes the lines in subsequent functions to the correct
source files.

a=jimblandy
r=nealsid


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@373 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
jimblandy@gmail.com 2009-08-05 00:54:47 +00:00
parent f6c98159e2
commit 15117f9ae0

View file

@ -153,6 +153,10 @@ struct SymbolInfo {
// than create FuncInfoList for such entries, we record their // than create FuncInfoList for such entries, we record their
// addresses here. These are not necessarily sorted. // addresses here. These are not necessarily sorted.
std::vector<ElfW(Addr)> file_boundaries; std::vector<ElfW(Addr)> file_boundaries;
// The current source file, for line number information. This is
// persistent across functions.
SourceFileInfo *current_source_file;
}; };
// Stab section name. // Stab section name.
@ -254,10 +258,8 @@ static int LoadLineInfo(struct nlist *list,
struct FuncInfo *func_info, struct FuncInfo *func_info,
const ElfW(Shdr) *stabstr_section) { const ElfW(Shdr) *stabstr_section) {
struct nlist *cur_list = list; struct nlist *cur_list = list;
// The source file to which subsequent lines belong.
SourceFileInfo *current_source_file = source_file_info;
// The name of the file any subsequent lines would belong to. // The name of the file any subsequent lines would belong to.
const char *last_source_name = current_source_file->name; const char *last_source_name = symbols->current_source_file->name;
do { do {
// Skip non line information. // Skip non line information.
while (cur_list < list_end && cur_list->n_type != N_SLINE) { while (cur_list < list_end && cur_list->n_type != N_SLINE) {
@ -276,9 +278,11 @@ static int LoadLineInfo(struct nlist *list,
struct LineInfo line; struct LineInfo line;
while (cur_list < list_end && cur_list->n_type == N_SLINE) { while (cur_list < list_end && cur_list->n_type == N_SLINE) {
// If this line is attributed to a new file, create its entry now. // If this line is attributed to a new file, create its entry now.
if (last_source_name != current_source_file->name) if (last_source_name != symbols->current_source_file->name) {
current_source_file = FindSourceFileInfo(symbols, last_source_name); symbols->current_source_file
line.file = current_source_file; = FindSourceFileInfo(symbols, last_source_name);
}
line.file = symbols->current_source_file;
line.rva_to_func = cur_list->n_value; line.rva_to_func = cur_list->n_value;
// n_desc is a signed short // n_desc is a signed short
line.line_num = (unsigned short)cur_list->n_desc; line.line_num = (unsigned short)cur_list->n_desc;
@ -466,6 +470,7 @@ static bool LoadSymbols(const ElfW(Shdr) *stab_section,
if (! source_file_info->addr) if (! source_file_info->addr)
symbols->main_files.push_back(source_file_info); symbols->main_files.push_back(source_file_info);
source_file_info->addr = cur_list->n_value; source_file_info->addr = cur_list->n_value;
symbols->current_source_file = source_file_info;
step = LoadFuncSymbols(cur_list, lists + nstab, symbols, step = LoadFuncSymbols(cur_list, lists + nstab, symbols,
source_file_info, stabstr_section); source_file_info, stabstr_section);
} else { } else {