Index: source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp @@ -446,26 +446,48 @@ const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data, const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list, FileSpecList &support_files) { + lldb::offset_t data_end = debug_line_data.GetByteSize(); lldb::offset_t offset = stmt_list; - Prologue prologue; - if (!ParsePrologue(debug_line_data, &offset, &prologue)) { - Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue " - "at 0x%8.8x (parsing ended around " - "0x%8.8" PRIx64 "\n", - stmt_list, offset); - return false; - } + // This loop runs once for regular compile units and may run multiple times + // for LTO optimized ones. + do { + Prologue prologue; + lldb::offset_t prologue_start = offset; + + if (!ParsePrologue(debug_line_data, &offset, &prologue)) { + Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue " + "at 0x%8.8x (parsing ended around " + "0x%8.8" PRIx64 "\n", + stmt_list, offset); + return false; + } - FileSpec file_spec; - std::string remapped_file; + FileSpec file_spec; + std::string remapped_file; + bool deduplicate = (prologue_start != stmt_list); + + // File index is only used for fetching information and not stored in the + // file spec entries. So we don't need to unify it over multiple prologues + // of the compile unit. + for (uint32_t file_idx = 1; + prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx) { + if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file)) + file_spec.SetFile(remapped_file, false, FileSpec::Style::native); + + // Avoid adding duplicate file specs from subsequent prologues. + if (deduplicate) + support_files.AppendIfUnique(file_spec); + else + support_files.Append(file_spec); + } + + // Only parse the prologue and skip the statement table. + // The prologue's total_length does not include the length field itself. + offset = prologue_start + prologue.total_length + + debug_line_data.GetDWARFSizeofInitialLength(); + } while (offset < data_end); - for (uint32_t file_idx = 1; - prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx) { - if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file)) - file_spec.SetFile(remapped_file, false, FileSpec::Style::native); - support_files.Append(file_spec); - } return true; } Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -992,6 +992,7 @@ LineTable *line_table; std::unique_ptr sequence_ap; lldb::addr_t addr_mask; + const FileSpecList &support_files; }; //---------------------------------------------------------------------- @@ -1014,9 +1015,23 @@ info->sequence_ap.reset(line_table->CreateLineSequenceContainer()); assert(info->sequence_ap.get()); } + + // If this is a compile unit with multiple prologues, figure out the + // file's index in the aggregated list of support files. + uint16_t file_idx = state.file; + if (file_idx > 0 && file_idx <= state.prologue->file_names.size()) { + const char *name = state.prologue->file_names[file_idx - 1].name; + FileSpec file_spec(name, false); + uint32_t promoted_idx = + info->support_files.FindFileIndex(0, file_spec, false); + + if (promoted_idx != UINT32_MAX && promoted_idx < UINT16_MAX) + file_idx = promoted_idx; + } + line_table->AppendLineEntryToSequence( info->sequence_ap.get(), state.address & info->addr_mask, state.line, - state.column, state.file, state.is_stmt, state.basic_block, + state.column, file_idx, state.is_stmt, state.basic_block, state.prologue_end, state.epilogue_begin, state.end_sequence); if (state.end_sequence) { // First, put the current sequence into the line table. @@ -1042,8 +1057,9 @@ if (cu_line_offset != DW_INVALID_OFFSET) { std::unique_ptr line_table_ap(new LineTable(sc.comp_unit)); if (line_table_ap.get()) { - ParseDWARFLineTableCallbackInfo info; - info.line_table = line_table_ap.get(); + const FileSpecList &support_files = sc.comp_unit->GetSupportFiles(); + ParseDWARFLineTableCallbackInfo info{line_table_ap.get(), nullptr, 0, + support_files}; /* * MIPS: @@ -1067,10 +1083,15 @@ break; } + const DWARFDataExtractor &debug_line_data = get_debug_line_data(); + lldb::offset_t data_end = debug_line_data.GetByteSize(); lldb::offset_t offset = cu_line_offset; - DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, - ParseDWARFLineTableCallback, - &info); + + do { + DWARFDebugLine::ParseStatementTable( + debug_line_data, &offset, ParseDWARFLineTableCallback, &info); + } while (offset < data_end); + SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); if (debug_map_symfile) { // We have an object file that has a line table with addresses that