diff options
Diffstat (limited to 'source/Symbol/LineTable.cpp')
-rw-r--r-- | source/Symbol/LineTable.cpp | 68 |
1 files changed, 41 insertions, 27 deletions
diff --git a/source/Symbol/LineTable.cpp b/source/Symbol/LineTable.cpp index 8d4d72c9a2a21..1433dc156d915 100644 --- a/source/Symbol/LineTable.cpp +++ b/source/Symbol/LineTable.cpp @@ -241,33 +241,47 @@ bool LineTable::FindLineEntryByAddress(const Address &so_addr, bool LineTable::ConvertEntryAtIndexToLineEntry(uint32_t idx, LineEntry &line_entry) { - if (idx < m_entries.size()) { - const Entry &entry = m_entries[idx]; - ModuleSP module_sp(m_comp_unit->GetModule()); - if (module_sp && - module_sp->ResolveFileAddress(entry.file_addr, - line_entry.range.GetBaseAddress())) { - if (!entry.is_terminal_entry && idx + 1 < m_entries.size()) - line_entry.range.SetByteSize(m_entries[idx + 1].file_addr - - entry.file_addr); - else - line_entry.range.SetByteSize(0); - - line_entry.file = - m_comp_unit->GetSupportFiles().GetFileSpecAtIndex(entry.file_idx); - line_entry.original_file = - m_comp_unit->GetSupportFiles().GetFileSpecAtIndex(entry.file_idx); - line_entry.line = entry.line; - line_entry.column = entry.column; - line_entry.is_start_of_statement = entry.is_start_of_statement; - line_entry.is_start_of_basic_block = entry.is_start_of_basic_block; - line_entry.is_prologue_end = entry.is_prologue_end; - line_entry.is_epilogue_begin = entry.is_epilogue_begin; - line_entry.is_terminal_entry = entry.is_terminal_entry; - return true; - } - } - return false; + if (idx >= m_entries.size()) + return false; + + const Entry &entry = m_entries[idx]; + ModuleSP module_sp(m_comp_unit->GetModule()); + if (!module_sp) + return false; + + addr_t file_addr = entry.file_addr; + + // A terminal entry can point outside of a module or a section. Decrement the + // address to ensure it resolves correctly. + if (entry.is_terminal_entry) + --file_addr; + + if (!module_sp->ResolveFileAddress(file_addr, + line_entry.range.GetBaseAddress())) + return false; + + // Now undo the decrement above. + if (entry.is_terminal_entry) + line_entry.range.GetBaseAddress().Slide(1); + + if (!entry.is_terminal_entry && idx + 1 < m_entries.size()) + line_entry.range.SetByteSize(m_entries[idx + 1].file_addr - + entry.file_addr); + else + line_entry.range.SetByteSize(0); + + line_entry.file = + m_comp_unit->GetSupportFiles().GetFileSpecAtIndex(entry.file_idx); + line_entry.original_file = + m_comp_unit->GetSupportFiles().GetFileSpecAtIndex(entry.file_idx); + line_entry.line = entry.line; + line_entry.column = entry.column; + line_entry.is_start_of_statement = entry.is_start_of_statement; + line_entry.is_start_of_basic_block = entry.is_start_of_basic_block; + line_entry.is_prologue_end = entry.is_prologue_end; + line_entry.is_epilogue_begin = entry.is_epilogue_begin; + line_entry.is_terminal_entry = entry.is_terminal_entry; + return true; } uint32_t LineTable::FindLineEntryIndexByFileIndex( |