aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/tools/lldb/source/Plugins/SymbolFile
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-22 19:14:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-22 19:14:02 +0000
commit580d4aa65a2dadf52a0abc9451ab25918cb25125 (patch)
treef57af07970c6653570799c317a2ebcf8ea056a10 /contrib/llvm/tools/lldb/source/Plugins/SymbolFile
parent22d1794578bafc3a0f25691c0531ba10d57713e6 (diff)
parent5f29bb8a675e8f96452b632e7129113f7dec850e (diff)
downloadsrc-580d4aa65a2dadf52a0abc9451ab25918cb25125.tar.gz
src-580d4aa65a2dadf52a0abc9451ab25918cb25125.zip
Merge lldb trunk r366426, resolve conflicts, and update FREEBSD-Xlist.
Notes
Notes: svn path=/projects/clang900-import/; revision=351400
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Plugins/SymbolFile')
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp558
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h116
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp22
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h12
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp69
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h83
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h7
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp3095
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h27
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp88
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h33
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp37
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h15
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp78
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h40
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp171
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h40
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp138
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h74
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp272
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h92
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp35
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h38
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp21
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h20
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp107
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h27
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp297
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h28
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp112
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h27
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp287
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h62
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp1097
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h200
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp375
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h44
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp39
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h26
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp111
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h42
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp7
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h7
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp37
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h24
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp11
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h11
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp243
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h44
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp374
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h54
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp18
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h15
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp23
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h37
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp631
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h209
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp58
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h14
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp98
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h32
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp16
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h16
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp162
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h25
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp31
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h17
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp1404
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h155
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp108
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h73
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp139
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h31
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp9
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h9
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp9
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h9
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp11
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h13
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp457
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h24
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp20
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h7
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp491
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h10
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp58
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h20
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp137
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h28
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp14
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h8
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp7
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h7
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp151
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h9
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp41
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h30
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp61
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h23
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp29
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h7
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp556
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h22
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp65
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h24
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp32
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h17
107 files changed, 6452 insertions, 8149 deletions
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index 2cca7a66b014..d4258274a38c 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -1,84 +1,166 @@
//===-- SymbolFileBreakpad.cpp ----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h"
+#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h"
#include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/FileSystem.h"
+#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/PostfixExpression.h"
+#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/StringExtras.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::breakpad;
-namespace {
-class LineIterator {
+class SymbolFileBreakpad::LineIterator {
public:
// begin iterator for sections of given type
- LineIterator(ObjectFile &obj, ConstString section_type)
- : m_obj(&obj), m_section_type(section_type), m_next_section_idx(0) {
+ LineIterator(ObjectFile &obj, Record::Kind section_type)
+ : m_obj(&obj), m_section_type(toString(section_type)),
+ m_next_section_idx(0), m_next_line(llvm::StringRef::npos) {
++*this;
}
+ // An iterator starting at the position given by the bookmark.
+ LineIterator(ObjectFile &obj, Record::Kind section_type, Bookmark bookmark);
+
// end iterator
explicit LineIterator(ObjectFile &obj)
: m_obj(&obj),
- m_next_section_idx(m_obj->GetSectionList()->GetNumSections(0)) {}
+ m_next_section_idx(m_obj->GetSectionList()->GetNumSections(0)),
+ m_current_line(llvm::StringRef::npos),
+ m_next_line(llvm::StringRef::npos) {}
friend bool operator!=(const LineIterator &lhs, const LineIterator &rhs) {
assert(lhs.m_obj == rhs.m_obj);
if (lhs.m_next_section_idx != rhs.m_next_section_idx)
return true;
- if (lhs.m_next_text.data() != rhs.m_next_text.data())
+ if (lhs.m_current_line != rhs.m_current_line)
return true;
- assert(lhs.m_current_text == rhs.m_current_text);
- assert(rhs.m_next_text == rhs.m_next_text);
+ assert(lhs.m_next_line == rhs.m_next_line);
return false;
}
const LineIterator &operator++();
- llvm::StringRef operator*() const { return m_current_text; }
+ llvm::StringRef operator*() const {
+ return m_section_text.slice(m_current_line, m_next_line);
+ }
+
+ Bookmark GetBookmark() const {
+ return Bookmark{m_next_section_idx, m_current_line};
+ }
private:
ObjectFile *m_obj;
ConstString m_section_type;
uint32_t m_next_section_idx;
- llvm::StringRef m_current_text;
- llvm::StringRef m_next_text;
+ llvm::StringRef m_section_text;
+ size_t m_current_line;
+ size_t m_next_line;
+
+ void FindNextLine() {
+ m_next_line = m_section_text.find('\n', m_current_line);
+ if (m_next_line != llvm::StringRef::npos) {
+ ++m_next_line;
+ if (m_next_line >= m_section_text.size())
+ m_next_line = llvm::StringRef::npos;
+ }
+ }
};
-} // namespace
-const LineIterator &LineIterator::operator++() {
+SymbolFileBreakpad::LineIterator::LineIterator(ObjectFile &obj,
+ Record::Kind section_type,
+ Bookmark bookmark)
+ : m_obj(&obj), m_section_type(toString(section_type)),
+ m_next_section_idx(bookmark.section), m_current_line(bookmark.offset) {
+ Section &sect =
+ *obj.GetSectionList()->GetSectionAtIndex(m_next_section_idx - 1);
+ assert(sect.GetName() == m_section_type);
+
+ DataExtractor data;
+ obj.ReadSectionData(&sect, data);
+ m_section_text = toStringRef(data.GetData());
+
+ assert(m_current_line < m_section_text.size());
+ FindNextLine();
+}
+
+const SymbolFileBreakpad::LineIterator &
+SymbolFileBreakpad::LineIterator::operator++() {
const SectionList &list = *m_obj->GetSectionList();
size_t num_sections = list.GetNumSections(0);
- while (m_next_text.empty() && m_next_section_idx < num_sections) {
+ while (m_next_line != llvm::StringRef::npos ||
+ m_next_section_idx < num_sections) {
+ if (m_next_line != llvm::StringRef::npos) {
+ m_current_line = m_next_line;
+ FindNextLine();
+ return *this;
+ }
+
Section &sect = *list.GetSectionAtIndex(m_next_section_idx++);
if (sect.GetName() != m_section_type)
continue;
DataExtractor data;
m_obj->ReadSectionData(&sect, data);
- m_next_text =
- llvm::StringRef(reinterpret_cast<const char *>(data.GetDataStart()),
- data.GetByteSize());
+ m_section_text = toStringRef(data.GetData());
+ m_next_line = 0;
}
- std::tie(m_current_text, m_next_text) = m_next_text.split('\n');
+ // We've reached the end.
+ m_current_line = m_next_line;
return *this;
}
-static llvm::iterator_range<LineIterator> lines(ObjectFile &obj,
- ConstString section_type) {
- return llvm::make_range(LineIterator(obj, section_type), LineIterator(obj));
+llvm::iterator_range<SymbolFileBreakpad::LineIterator>
+SymbolFileBreakpad::lines(Record::Kind section_type) {
+ return llvm::make_range(LineIterator(*m_obj_file, section_type),
+ LineIterator(*m_obj_file));
+}
+
+namespace {
+// A helper class for constructing the list of support files for a given compile
+// unit.
+class SupportFileMap {
+public:
+ // Given a breakpad file ID, return a file ID to be used in the support files
+ // for this compile unit.
+ size_t operator[](size_t file) {
+ return m_map.try_emplace(file, m_map.size() + 1).first->second;
+ }
+
+ // Construct a FileSpecList containing only the support files relevant for
+ // this compile unit (in the correct order).
+ FileSpecList translate(const FileSpec &cu_spec,
+ llvm::ArrayRef<FileSpec> all_files);
+
+private:
+ llvm::DenseMap<size_t, size_t> m_map;
+};
+} // namespace
+
+FileSpecList SupportFileMap::translate(const FileSpec &cu_spec,
+ llvm::ArrayRef<FileSpec> all_files) {
+ std::vector<FileSpec> result;
+ result.resize(m_map.size() + 1);
+ result[0] = cu_spec;
+ for (const auto &KV : m_map) {
+ if (KV.first < all_files.size())
+ result[KV.second] = all_files[KV.first];
+ }
+ return FileSpecList(std::move(result));
}
void SymbolFileBreakpad::Initialize() {
@@ -102,17 +184,42 @@ uint32_t SymbolFileBreakpad::CalculateAbilities() {
if (m_obj_file->GetPluginName() != ObjectFileBreakpad::GetPluginNameStatic())
return 0;
- return CompileUnits | Functions;
+ return CompileUnits | Functions | LineTables;
}
uint32_t SymbolFileBreakpad::GetNumCompileUnits() {
- // TODO
- return 0;
+ ParseCUData();
+ return m_cu_data->GetSize();
}
CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) {
- // TODO
- return nullptr;
+ if (index >= m_cu_data->GetSize())
+ return nullptr;
+
+ CompUnitData &data = m_cu_data->GetEntryRef(index).data;
+
+ ParseFileRecords();
+
+ FileSpec spec;
+
+ // The FileSpec of the compile unit will be the file corresponding to the
+ // first LINE record.
+ LineIterator It(*m_obj_file, Record::Func, data.bookmark), End(*m_obj_file);
+ assert(Record::classify(*It) == Record::Func);
+ ++It; // Skip FUNC record.
+ if (It != End) {
+ auto record = LineRecord::parse(*It);
+ if (record && record->FileNum < m_files->size())
+ spec = (*m_files)[record->FileNum];
+ }
+
+ auto cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(),
+ /*user_data*/ nullptr, spec, index,
+ eLanguageTypeUnknown,
+ /*is_optimized*/ eLazyBoolNo);
+
+ GetSymbolVendor().SetCompileUnitAtIndex(index, cu_sp);
+ return cu_sp;
}
size_t SymbolFileBreakpad::ParseFunctions(CompileUnit &comp_unit) {
@@ -121,20 +228,67 @@ size_t SymbolFileBreakpad::ParseFunctions(CompileUnit &comp_unit) {
}
bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) {
- // TODO
- return 0;
+ CompUnitData &data = m_cu_data->GetEntryRef(comp_unit.GetID()).data;
+
+ if (!data.line_table_up)
+ ParseLineTableAndSupportFiles(comp_unit, data);
+
+ comp_unit.SetLineTable(data.line_table_up.release());
+ return true;
+}
+
+bool SymbolFileBreakpad::ParseSupportFiles(CompileUnit &comp_unit,
+ FileSpecList &support_files) {
+ CompUnitData &data = m_cu_data->GetEntryRef(comp_unit.GetID()).data;
+ if (!data.support_files)
+ ParseLineTableAndSupportFiles(comp_unit, data);
+
+ support_files = std::move(*data.support_files);
+ return true;
}
uint32_t
SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
- // TODO
- return 0;
+ if (!(resolve_scope & (eSymbolContextCompUnit | eSymbolContextLineEntry)))
+ return 0;
+
+ ParseCUData();
+ uint32_t idx =
+ m_cu_data->FindEntryIndexThatContains(so_addr.GetFileAddress());
+ if (idx == UINT32_MAX)
+ return 0;
+
+ sc.comp_unit = GetSymbolVendor().GetCompileUnitAtIndex(idx).get();
+ SymbolContextItem result = eSymbolContextCompUnit;
+ if (resolve_scope & eSymbolContextLineEntry) {
+ if (sc.comp_unit->GetLineTable()->FindLineEntryByAddress(so_addr,
+ sc.line_entry)) {
+ result |= eSymbolContextLineEntry;
+ }
+ }
+
+ return result;
+}
+
+uint32_t SymbolFileBreakpad::ResolveSymbolContext(
+ const FileSpec &file_spec, uint32_t line, bool check_inlines,
+ lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
+ if (!(resolve_scope & eSymbolContextCompUnit))
+ return 0;
+
+ uint32_t old_size = sc_list.GetSize();
+ for (size_t i = 0, size = GetNumCompileUnits(); i < size; ++i) {
+ CompileUnit &cu = *GetSymbolVendor().GetCompileUnitAtIndex(i);
+ cu.ResolveSymbolContext(file_spec, line, check_inlines,
+ /*exact*/ false, resolve_scope, sc_list);
+ }
+ return sc_list.GetSize() - old_size;
}
uint32_t SymbolFileBreakpad::FindFunctions(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
FunctionNameType name_type_mask, bool include_inlines, bool append,
SymbolContextList &sc_list) {
// TODO
@@ -153,7 +307,7 @@ uint32_t SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
}
uint32_t SymbolFileBreakpad::FindTypes(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
bool append, uint32_t max_matches,
llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
if (!append)
@@ -172,7 +326,7 @@ SymbolFileBreakpad::FindTypes(const std::vector<CompilerContext> &context,
void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
Module &module = *m_obj_file->GetModule();
- addr_t base = module.GetObjectFile()->GetBaseAddress().GetFileAddress();
+ addr_t base = GetBaseFileAddress();
if (base == LLDB_INVALID_ADDRESS) {
LLDB_LOG(log, "Unable to fetch the base address of object file. Skipping "
"symtab population.");
@@ -180,44 +334,320 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
}
const SectionList &list = *module.GetSectionList();
- for (llvm::StringRef line : lines(*m_obj_file, ConstString("PUBLIC"))) {
- // PUBLIC [m] address param_size name
- // skip PUBLIC keyword
- line = getToken(line).second;
- llvm::StringRef token;
- std::tie(token, line) = getToken(line);
- if (token == "m")
- std::tie(token, line) = getToken(line);
-
- addr_t address;
- if (!to_integer(token, address, 16))
- continue;
+ llvm::DenseMap<addr_t, Symbol> symbols;
+ auto add_symbol = [&](addr_t address, llvm::Optional<addr_t> size,
+ llvm::StringRef name) {
address += base;
-
- // skip param_size
- line = getToken(line).second;
-
- llvm::StringRef name = line.trim();
-
SectionSP section_sp = list.FindSectionContainingFileAddress(address);
if (!section_sp) {
LLDB_LOG(log,
"Ignoring symbol {0}, whose address ({1}) is outside of the "
"object file. Mismatched symbol file?",
name, address);
+ return;
+ }
+ symbols.try_emplace(
+ address, /*symID*/ 0, Mangled(name, /*is_mangled*/ false),
+ eSymbolTypeCode, /*is_global*/ true, /*is_debug*/ false,
+ /*is_trampoline*/ false, /*is_artificial*/ false,
+ AddressRange(section_sp, address - section_sp->GetFileAddress(),
+ size.getValueOr(0)),
+ size.hasValue(), /*contains_linker_annotations*/ false, /*flags*/ 0);
+ };
+
+ for (llvm::StringRef line : lines(Record::Func)) {
+ if (auto record = FuncRecord::parse(line))
+ add_symbol(record->Address, record->Size, record->Name);
+ }
+
+ for (llvm::StringRef line : lines(Record::Public)) {
+ if (auto record = PublicRecord::parse(line))
+ add_symbol(record->Address, llvm::None, record->Name);
+ else
+ LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", line);
+ }
+
+ for (auto &KV : symbols)
+ symtab.AddSymbol(std::move(KV.second));
+ symtab.CalculateSymbolSizes();
+}
+
+static llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>>
+GetRule(llvm::StringRef &unwind_rules) {
+ // Unwind rules are of the form
+ // register1: expression1 register2: expression2 ...
+ // We assume none of the tokens in expression<n> end with a colon.
+
+ llvm::StringRef lhs, rest;
+ std::tie(lhs, rest) = getToken(unwind_rules);
+ if (!lhs.consume_back(":"))
+ return llvm::None;
+
+ // Seek forward to the next register: expression pair
+ llvm::StringRef::size_type pos = rest.find(": ");
+ if (pos == llvm::StringRef::npos) {
+ // No pair found, this means the rest of the string is a single expression.
+ unwind_rules = llvm::StringRef();
+ return std::make_pair(lhs, rest);
+ }
+
+ // Go back one token to find the end of the current rule.
+ pos = rest.rfind(' ', pos);
+ if (pos == llvm::StringRef::npos)
+ return llvm::None;
+
+ llvm::StringRef rhs = rest.take_front(pos);
+ unwind_rules = rest.drop_front(pos);
+ return std::make_pair(lhs, rhs);
+}
+
+static const RegisterInfo *
+ResolveRegister(const SymbolFile::RegisterInfoResolver &resolver,
+ llvm::StringRef name) {
+ if (name.consume_front("$"))
+ return resolver.ResolveName(name);
+
+ return nullptr;
+}
+
+static const RegisterInfo *
+ResolveRegisterOrRA(const SymbolFile::RegisterInfoResolver &resolver,
+ llvm::StringRef name) {
+ if (name == ".ra")
+ return resolver.ResolveNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ return ResolveRegister(resolver, name);
+}
+
+bool SymbolFileBreakpad::ParseUnwindRow(llvm::StringRef unwind_rules,
+ const RegisterInfoResolver &resolver,
+ UnwindPlan::Row &row) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
+
+ llvm::BumpPtrAllocator node_alloc;
+ while (auto rule = GetRule(unwind_rules)) {
+ node_alloc.Reset();
+ llvm::StringRef lhs = rule->first;
+ postfix::Node *rhs = postfix::Parse(rule->second, node_alloc);
+ if (!rhs) {
+ LLDB_LOG(log, "Could not parse `{0}` as unwind rhs.", rule->second);
+ return false;
+ }
+
+ bool success = postfix::ResolveSymbols(
+ rhs, [&](postfix::SymbolNode &symbol) -> postfix::Node * {
+ llvm::StringRef name = symbol.GetName();
+ if (name == ".cfa" && lhs != ".cfa")
+ return postfix::MakeNode<postfix::InitialValueNode>(node_alloc);
+
+ if (const RegisterInfo *info = ResolveRegister(resolver, name)) {
+ return postfix::MakeNode<postfix::RegisterNode>(
+ node_alloc, info->kinds[eRegisterKindLLDB]);
+ }
+ return nullptr;
+ });
+
+ if (!success) {
+ LLDB_LOG(log, "Resolving symbols in `{0}` failed.", rule->second);
+ return false;
+ }
+
+ ArchSpec arch = m_obj_file->GetArchitecture();
+ StreamString dwarf(Stream::eBinary, arch.GetAddressByteSize(),
+ arch.GetByteOrder());
+ ToDWARF(*rhs, dwarf);
+ uint8_t *saved = m_allocator.Allocate<uint8_t>(dwarf.GetSize());
+ std::memcpy(saved, dwarf.GetData(), dwarf.GetSize());
+
+ if (lhs == ".cfa") {
+ row.GetCFAValue().SetIsDWARFExpression(saved, dwarf.GetSize());
+ } else if (const RegisterInfo *info = ResolveRegisterOrRA(resolver, lhs)) {
+ UnwindPlan::Row::RegisterLocation loc;
+ loc.SetIsDWARFExpression(saved, dwarf.GetSize());
+ row.SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc);
+ } else
+ LLDB_LOG(log, "Invalid register `{0}` in unwind rule.", lhs);
+ }
+ if (unwind_rules.empty())
+ return true;
+
+ LLDB_LOG(log, "Could not parse `{0}` as an unwind rule.", unwind_rules);
+ return false;
+}
+
+UnwindPlanSP
+SymbolFileBreakpad::GetUnwindPlan(const Address &address,
+ const RegisterInfoResolver &resolver) {
+ ParseUnwindData();
+ const UnwindMap::Entry *entry =
+ m_unwind_data->FindEntryThatContains(address.GetFileAddress());
+ if (!entry)
+ return nullptr;
+
+ addr_t base = GetBaseFileAddress();
+ if (base == LLDB_INVALID_ADDRESS)
+ return nullptr;
+
+ LineIterator It(*m_obj_file, Record::StackCFI, entry->data), End(*m_obj_file);
+ llvm::Optional<StackCFIRecord> init_record = StackCFIRecord::parse(*It);
+ assert(init_record.hasValue());
+ assert(init_record->Size.hasValue());
+
+ auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB);
+ plan_sp->SetSourceName("breakpad STACK CFI");
+ plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
+ plan_sp->SetPlanValidAddressRange(
+ AddressRange(base + init_record->Address, *init_record->Size,
+ m_obj_file->GetModule()->GetSectionList()));
+
+ auto row_sp = std::make_shared<UnwindPlan::Row>();
+ row_sp->SetOffset(0);
+ if (!ParseUnwindRow(init_record->UnwindRules, resolver, *row_sp))
+ return nullptr;
+ plan_sp->AppendRow(row_sp);
+ for (++It; It != End; ++It) {
+ llvm::Optional<StackCFIRecord> record = StackCFIRecord::parse(*It);
+ if (!record.hasValue())
+ return nullptr;
+ if (record->Size.hasValue())
+ break;
+
+ row_sp = std::make_shared<UnwindPlan::Row>(*row_sp);
+ row_sp->SetOffset(record->Address - init_record->Address);
+ if (!ParseUnwindRow(record->UnwindRules, resolver, *row_sp))
+ return nullptr;
+ plan_sp->AppendRow(row_sp);
+ }
+ return plan_sp;
+}
+
+SymbolVendor &SymbolFileBreakpad::GetSymbolVendor() {
+ return *m_obj_file->GetModule()->GetSymbolVendor();
+}
+
+addr_t SymbolFileBreakpad::GetBaseFileAddress() {
+ return m_obj_file->GetModule()
+ ->GetObjectFile()
+ ->GetBaseAddress()
+ .GetFileAddress();
+}
+
+// Parse out all the FILE records from the breakpad file. These will be needed
+// when constructing the support file lists for individual compile units.
+void SymbolFileBreakpad::ParseFileRecords() {
+ if (m_files)
+ return;
+ m_files.emplace();
+
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
+ for (llvm::StringRef line : lines(Record::File)) {
+ auto record = FileRecord::parse(line);
+ if (!record) {
+ LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", line);
continue;
}
- symtab.AddSymbol(Symbol(
- /*symID*/ 0, Mangled(name, /*is_mangled*/ false), eSymbolTypeCode,
- /*is_global*/ true, /*is_debug*/ false, /*is_trampoline*/ false,
- /*is_artificial*/ false,
- AddressRange(section_sp, address - section_sp->GetFileAddress(), 0),
- /*size_is_valid*/ 0, /*contains_linker_annotations*/ false,
- /*flags*/ 0));
+ if (record->Number >= m_files->size())
+ m_files->resize(record->Number + 1);
+ FileSpec::Style style = FileSpec::GuessPathStyle(record->Name)
+ .getValueOr(FileSpec::Style::native);
+ (*m_files)[record->Number] = FileSpec(record->Name, style);
}
+}
- // TODO: Process FUNC records as well.
+void SymbolFileBreakpad::ParseCUData() {
+ if (m_cu_data)
+ return;
- symtab.CalculateSymbolSizes();
+ m_cu_data.emplace();
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
+ addr_t base = GetBaseFileAddress();
+ if (base == LLDB_INVALID_ADDRESS) {
+ LLDB_LOG(log, "SymbolFile parsing failed: Unable to fetch the base address "
+ "of object file.");
+ }
+
+ // We shall create one compile unit for each FUNC record. So, count the number
+ // of FUNC records, and store them in m_cu_data, together with their ranges.
+ for (LineIterator It(*m_obj_file, Record::Func), End(*m_obj_file); It != End;
+ ++It) {
+ if (auto record = FuncRecord::parse(*It)) {
+ m_cu_data->Append(CompUnitMap::Entry(base + record->Address, record->Size,
+ CompUnitData(It.GetBookmark())));
+ } else
+ LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", *It);
+ }
+ m_cu_data->Sort();
+}
+
+// Construct the list of support files and line table entries for the given
+// compile unit.
+void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
+ CompUnitData &data) {
+ addr_t base = GetBaseFileAddress();
+ assert(base != LLDB_INVALID_ADDRESS &&
+ "How did we create compile units without a base address?");
+
+ SupportFileMap map;
+ data.line_table_up = llvm::make_unique<LineTable>(&cu);
+ std::unique_ptr<LineSequence> line_seq_up(
+ data.line_table_up->CreateLineSequenceContainer());
+ llvm::Optional<addr_t> next_addr;
+ auto finish_sequence = [&]() {
+ data.line_table_up->AppendLineEntryToSequence(
+ line_seq_up.get(), *next_addr, /*line*/ 0, /*column*/ 0,
+ /*file_idx*/ 0, /*is_start_of_statement*/ false,
+ /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false,
+ /*is_epilogue_begin*/ false, /*is_terminal_entry*/ true);
+ data.line_table_up->InsertSequence(line_seq_up.get());
+ line_seq_up->Clear();
+ };
+
+ LineIterator It(*m_obj_file, Record::Func, data.bookmark), End(*m_obj_file);
+ assert(Record::classify(*It) == Record::Func);
+ for (++It; It != End; ++It) {
+ auto record = LineRecord::parse(*It);
+ if (!record)
+ break;
+
+ record->Address += base;
+
+ if (next_addr && *next_addr != record->Address) {
+ // Discontiguous entries. Finish off the previous sequence and reset.
+ finish_sequence();
+ }
+ data.line_table_up->AppendLineEntryToSequence(
+ line_seq_up.get(), record->Address, record->LineNum, /*column*/ 0,
+ map[record->FileNum], /*is_start_of_statement*/ true,
+ /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false,
+ /*is_epilogue_begin*/ false, /*is_terminal_entry*/ false);
+ next_addr = record->Address + record->Size;
+ }
+ if (next_addr)
+ finish_sequence();
+ data.support_files = map.translate(cu, *m_files);
+}
+
+void SymbolFileBreakpad::ParseUnwindData() {
+ if (m_unwind_data)
+ return;
+
+ m_unwind_data.emplace();
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
+ addr_t base = GetBaseFileAddress();
+ if (base == LLDB_INVALID_ADDRESS) {
+ LLDB_LOG(log, "SymbolFile parsing failed: Unable to fetch the base address "
+ "of object file.");
+ }
+
+ for (LineIterator It(*m_obj_file, Record::StackCFI), End(*m_obj_file);
+ It != End; ++It) {
+ if (auto record = StackCFIRecord::parse(*It)) {
+ if (record->Size)
+ m_unwind_data->Append(UnwindMap::Entry(
+ base + record->Address, *record->Size, It.GetBookmark()));
+ } else
+ LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", *It);
+ }
+ m_unwind_data->Sort();
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
index 68e8d11c7dd7..8a0b7645fd0a 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -1,16 +1,19 @@
//===-- SymbolFileBreakpad.h ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
#define LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
+#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h"
+#include "lldb/Core/FileSpecList.h"
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/UnwindPlan.h"
namespace lldb_private {
@@ -18,9 +21,7 @@ namespace breakpad {
class SymbolFileBreakpad : public SymbolFile {
public:
- //------------------------------------------------------------------
// Static Functions
- //------------------------------------------------------------------
static void Initialize();
static void Terminate();
static void DebuggerInitialize(Debugger &debugger) {}
@@ -34,9 +35,7 @@ public:
return new SymbolFileBreakpad(obj_file);
}
- //------------------------------------------------------------------
// Constructors and Destructors
- //------------------------------------------------------------------
SymbolFileBreakpad(ObjectFile *object_file) : SymbolFile(object_file) {}
~SymbolFileBreakpad() override {}
@@ -45,9 +44,7 @@ public:
void InitializeObject() override {}
- //------------------------------------------------------------------
// Compile Unit function calls
- //------------------------------------------------------------------
uint32_t GetNumCompileUnits() override;
@@ -64,20 +61,18 @@ public:
bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; }
bool ParseSupportFiles(CompileUnit &comp_unit,
- FileSpecList &support_files) override {
- return false;
- }
+ FileSpecList &support_files) override;
size_t ParseTypes(CompileUnit &cu) override { return 0; }
- bool
- ParseImportedModules(const SymbolContext &sc,
- std::vector<ConstString> &imported_modules) override {
+ bool ParseImportedModules(
+ const SymbolContext &sc,
+ std::vector<lldb_private::SourceModule> &imported_modules) override {
return false;
}
size_t ParseBlocksRecursive(Function &func) override { return 0; }
- uint32_t FindGlobalVariables(const ConstString &name,
+ uint32_t FindGlobalVariables(ConstString name,
const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
VariableList &variables) override {
@@ -99,12 +94,17 @@ public:
lldb::SymbolContextItem resolve_scope,
SymbolContext &sc) override;
+ uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line,
+ bool check_inlines,
+ lldb::SymbolContextItem resolve_scope,
+ SymbolContextList &sc_list) override;
+
size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
TypeList &type_list) override {
return 0;
}
- uint32_t FindFunctions(const ConstString &name,
+ uint32_t FindFunctions(ConstString name,
const CompilerDeclContext *parent_decl_ctx,
lldb::FunctionNameType name_type_mask,
bool include_inlines, bool append,
@@ -113,7 +113,7 @@ public:
uint32_t FindFunctions(const RegularExpression &regex, bool include_inlines,
bool append, SymbolContextList &sc_list) override;
- uint32_t FindTypes(const ConstString &name,
+ uint32_t FindTypes(ConstString name,
const CompilerDeclContext *parent_decl_ctx, bool append,
uint32_t max_matches,
llvm::DenseSet<SymbolFile *> &searched_symbol_files,
@@ -127,17 +127,93 @@ public:
}
CompilerDeclContext
- FindNamespace(const ConstString &name,
+ FindNamespace(ConstString name,
const CompilerDeclContext *parent_decl_ctx) override {
return CompilerDeclContext();
}
void AddSymbols(Symtab &symtab) override;
+ lldb::UnwindPlanSP
+ GetUnwindPlan(const Address &address,
+ const RegisterInfoResolver &resolver) override;
+
ConstString GetPluginName() override { return GetPluginNameStatic(); }
uint32_t GetPluginVersion() override { return 1; }
private:
+ // A class representing a position in the breakpad file. Useful for
+ // remembering the position so we can go back to it later and parse more data.
+ // Can be converted to/from a LineIterator, but it has a much smaller memory
+ // footprint.
+ struct Bookmark {
+ uint32_t section;
+ size_t offset;
+
+ friend bool operator<(const Bookmark &lhs, const Bookmark &rhs) {
+ return std::tie(lhs.section, lhs.offset) <
+ std::tie(rhs.section, rhs.offset);
+ }
+ };
+
+ // At iterator class for simplifying algorithms reading data from the breakpad
+ // file. It iterates over all records (lines) in the sections of a given type.
+ // It also supports saving a specific position (via the GetBookmark() method)
+ // and then resuming from it afterwards.
+ class LineIterator;
+
+ // Return an iterator range for all records in the given object file of the
+ // given type.
+ llvm::iterator_range<LineIterator> lines(Record::Kind section_type);
+
+ // Breakpad files do not contain sufficient information to correctly
+ // reconstruct compile units. The approach chosen here is to treat each
+ // function as a compile unit. The compile unit name is the name if the first
+ // line entry belonging to this function.
+ // This class is our internal representation of a compile unit. It stores the
+ // CompileUnit object and a bookmark pointing to the FUNC record of the
+ // compile unit function. It also lazily construct the list of support files
+ // and line table entries for the compile unit, when these are needed.
+ class CompUnitData {
+ public:
+ CompUnitData(Bookmark bookmark) : bookmark(bookmark) {}
+
+ CompUnitData() = default;
+ CompUnitData(const CompUnitData &rhs) : bookmark(rhs.bookmark) {}
+ CompUnitData &operator=(const CompUnitData &rhs) {
+ bookmark = rhs.bookmark;
+ support_files.reset();
+ line_table_up.reset();
+ return *this;
+ }
+ friend bool operator<(const CompUnitData &lhs, const CompUnitData &rhs) {
+ return lhs.bookmark < rhs.bookmark;
+ }
+
+ Bookmark bookmark;
+ llvm::Optional<FileSpecList> support_files;
+ std::unique_ptr<LineTable> line_table_up;
+
+ };
+
+ SymbolVendor &GetSymbolVendor();
+ lldb::addr_t GetBaseFileAddress();
+ void ParseFileRecords();
+ void ParseCUData();
+ void ParseLineTableAndSupportFiles(CompileUnit &cu, CompUnitData &data);
+ void ParseUnwindData();
+ bool ParseUnwindRow(llvm::StringRef unwind_rules,
+ const RegisterInfoResolver &resolver,
+ UnwindPlan::Row &row);
+
+ using CompUnitMap = RangeDataVector<lldb::addr_t, lldb::addr_t, CompUnitData>;
+
+ llvm::Optional<std::vector<FileSpec>> m_files;
+ llvm::Optional<CompUnitMap> m_cu_data;
+
+ using UnwindMap = RangeDataVector<lldb::addr_t, lldb::addr_t, Bookmark>;
+ llvm::Optional<UnwindMap> m_unwind_data;
+ llvm::BumpPtrAllocator m_allocator;
};
} // namespace breakpad
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
index db75cf9c3bb3..9ae047da1325 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
@@ -1,14 +1,12 @@
//===-- AppleDWARFIndex.cpp ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "Plugins/SymbolFile/DWARF/AppleDWARFIndex.h"
-#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
@@ -75,8 +73,8 @@ void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
return;
DWARFMappedHash::DIEInfoArray hash_data;
- if (m_apple_names_up->AppendAllDIEsInRange(
- cu.GetOffset(), cu.GetNextCompileUnitOffset(), hash_data))
+ if (m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(),
+ cu.GetNextUnitOffset(), hash_data))
DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
}
@@ -134,14 +132,14 @@ void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets);
}
-void AppleDWARFIndex::GetFunctions(ConstString name, DWARFDebugInfo &info,
+void AppleDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
uint32_t name_type_mask,
std::vector<DWARFDIE> &dies) {
DIEArray offsets;
m_apple_names_up->FindByName(name.GetStringRef(), offsets);
for (const DIERef &die_ref : offsets) {
- ProcessFunctionDIE(name.GetStringRef(), die_ref, info, parent_decl_ctx,
+ ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, parent_decl_ctx,
name_type_mask, dies);
}
}
@@ -156,12 +154,12 @@ void AppleDWARFIndex::GetFunctions(const RegularExpression &regex,
DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
}
-void AppleDWARFIndex::ReportInvalidDIEOffset(dw_offset_t offset,
- llvm::StringRef name) {
+void AppleDWARFIndex::ReportInvalidDIERef(const DIERef &ref,
+ llvm::StringRef name) {
m_module.ReportErrorIfModifyDetected(
"the DWARF debug information has been modified (accelerator table had "
"bad die 0x%8.8x for '%s')\n",
- offset, name.str().c_str());
+ ref.die_offset(), name.str().c_str());
}
void AppleDWARFIndex::Dump(Stream &s) {
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
index ea133d0e73cf..d15d61e270b3 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
@@ -1,9 +1,8 @@
//===-- AppleDWARFIndex.h --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -43,14 +42,13 @@ public:
void GetTypes(ConstString name, DIEArray &offsets) override;
void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
void GetNamespaces(ConstString name, DIEArray &offsets) override;
- void GetFunctions(ConstString name, DWARFDebugInfo &info,
+ void GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
uint32_t name_type_mask,
std::vector<DWARFDIE> &dies) override;
void GetFunctions(const RegularExpression &regex, DIEArray &offsets) override;
- void ReportInvalidDIEOffset(dw_offset_t offset,
- llvm::StringRef name) override;
+ void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override;
void Dump(Stream &s) override;
private:
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
index 0cd0f0c0272a..f7f2a5bf006b 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -1,67 +1,18 @@
//===-- DIERef.cpp ----------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DIERef.h"
-#include "DWARFUnit.h"
-#include "DWARFDebugInfo.h"
-#include "DWARFFormValue.h"
-#include "SymbolFileDWARF.h"
-#include "SymbolFileDWARFDebugMap.h"
-
-DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf)
- : cu_offset(DW_INVALID_OFFSET), die_offset(uid & 0xffffffff) {
- SymbolFileDWARFDebugMap *debug_map = dwarf->GetDebugMapSymfile();
- if (debug_map) {
- const uint32_t oso_idx = debug_map->GetOSOIndexFromUserID(uid);
- SymbolFileDWARF *actual_dwarf = debug_map->GetSymbolFileByOSOIndex(oso_idx);
- if (actual_dwarf) {
- DWARFDebugInfo *debug_info = actual_dwarf->DebugInfo();
- if (debug_info) {
- DWARFUnit *dwarf_cu =
- debug_info->GetCompileUnitContainingDIEOffset(die_offset);
- if (dwarf_cu) {
- cu_offset = dwarf_cu->GetOffset();
- return;
- }
- }
- }
- die_offset = DW_INVALID_OFFSET;
- } else {
- cu_offset = uid >> 32;
- }
-}
-
-DIERef::DIERef(const DWARFFormValue &form_value)
- : cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET) {
- if (form_value.IsValid()) {
- const DWARFUnit *dwarf_cu = form_value.GetCompileUnit();
- if (dwarf_cu) {
- if (dwarf_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
- cu_offset = dwarf_cu->GetBaseObjOffset();
- else
- cu_offset = dwarf_cu->GetOffset();
- }
- die_offset = form_value.Reference();
- }
-}
+#include "llvm/Support/Format.h"
-lldb::user_id_t DIERef::GetUID(SymbolFileDWARF *dwarf) const {
- //----------------------------------------------------------------------
- // Each SymbolFileDWARF will set its ID to what is expected.
- //
- // SymbolFileDWARF, when used for DWARF with .o files on MacOSX, has the
- // ID set to the compile unit index.
- //
- // SymbolFileDWARFDwo sets the ID to the compile unit offset.
- //----------------------------------------------------------------------
- if (dwarf && die_offset != DW_INVALID_OFFSET)
- return dwarf->GetID() | die_offset;
- else
- return LLDB_INVALID_UID;
+void llvm::format_provider<DIERef>::format(const DIERef &ref, raw_ostream &OS,
+ StringRef Style) {
+ if (ref.dwo_num())
+ OS << format_hex_no_prefix(*ref.dwo_num(), 8) << "/";
+ OS << (ref.section() == DIERef::DebugInfo ? "INFO" : "TYPE");
+ OS << "/" << format_hex_no_prefix(ref.die_offset(), 8);
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
index cb28c890c25a..5546bb7e8b86 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
@@ -1,9 +1,8 @@
//===-- DIERef.h ------------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,48 +10,54 @@
#define SymbolFileDWARF_DIERef_h_
#include "lldb/Core/dwarf.h"
-#include "lldb/lldb-defines.h"
-
-class DWARFFormValue;
-class SymbolFileDWARF;
-
-struct DIERef {
- DIERef() = default;
-
- DIERef(dw_offset_t c, dw_offset_t d) : cu_offset(c), die_offset(d) {}
-
- //----------------------------------------------------------------------
- // In order to properly decode a lldb::user_id_t back into a DIERef we
- // need the DWARF file since it knows if DWARF in .o files is being used
- // (MacOSX) or if DWO files are being used. The encoding of the user ID
- // differs between the two types of DWARF.
- //----------------------------------------------------------------------
- explicit DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf);
-
- explicit DIERef(const DWARFFormValue &form_value);
-
- //----------------------------------------------------------------------
- // In order to properly encode a DIERef unto a lldb::user_id_t we need
- // the DWARF file since it knows if DWARF in .o files is being used
- // (MacOSX) or if DWO files are being used. The encoding of the user ID
- // differs between the two types of DWARF.
- //----------------------------------------------------------------------
- lldb::user_id_t GetUID(SymbolFileDWARF *dwarf) const;
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/FormatProviders.h"
+#include <cassert>
+#include <vector>
+
+/// Identifies a DWARF debug info entry within a given Module. It contains three
+/// "coordinates":
+/// - dwo_num: identifies the dwo file in the Module. If this field is not set,
+/// the DIERef references the main file.
+/// - section: identifies the section of the debug info entry in the given file:
+/// debug_info or debug_types.
+/// - die_offset: The offset of the debug info entry as an absolute offset from
+/// the beginning of the section specified in the section field.
+class DIERef {
+public:
+ enum Section : uint8_t { DebugInfo, DebugTypes };
+
+ DIERef(llvm::Optional<uint32_t> dwo_num, Section section,
+ dw_offset_t die_offset)
+ : m_dwo_num(dwo_num.getValueOr(0)), m_dwo_num_valid(bool(dwo_num)),
+ m_section(section), m_die_offset(die_offset) {
+ assert(this->dwo_num() == dwo_num && "Dwo number out of range?");
+ }
- bool operator<(const DIERef &ref) const {
- return die_offset < ref.die_offset;
+ llvm::Optional<uint32_t> dwo_num() const {
+ if (m_dwo_num_valid)
+ return m_dwo_num;
+ return llvm::None;
}
- bool operator<(const DIERef &ref) { return die_offset < ref.die_offset; }
+ Section section() const { return static_cast<Section>(m_section); }
- explicit operator bool() const {
- return cu_offset != DW_INVALID_OFFSET || die_offset != DW_INVALID_OFFSET;
- }
+ dw_offset_t die_offset() const { return m_die_offset; }
- dw_offset_t cu_offset = DW_INVALID_OFFSET;
- dw_offset_t die_offset = DW_INVALID_OFFSET;
+private:
+ uint32_t m_dwo_num : 30;
+ uint32_t m_dwo_num_valid : 1;
+ uint32_t m_section : 1;
+ dw_offset_t m_die_offset;
};
+static_assert(sizeof(DIERef) == 8, "");
typedef std::vector<DIERef> DIEArray;
+namespace llvm {
+template<> struct format_provider<DIERef> {
+ static void format(const DIERef &ref, raw_ostream &OS, StringRef Style);
+};
+} // namespace llvm
+
#endif // SymbolFileDWARF_DIERef_h_
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index 24d5f26745dc..e7927b31b9c3 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -1,9 +1,8 @@
//===-- DWARFASTParser.h ----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 70d48e5f1dfa..b85ab54a10d3 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1,9 +1,8 @@
//===-- DWARFASTParserClang.cpp ---------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,7 +10,6 @@
#include "DWARFASTParserClang.h"
#include "DWARFDIE.h"
-#include "DWARFDIECollection.h"
#include "DWARFDebugInfo.h"
#include "DWARFDeclContext.h"
#include "DWARFDefines.h"
@@ -44,6 +42,7 @@
#include "clang/AST/DeclTemplate.h"
#include <map>
+#include <memory>
#include <vector>
//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
@@ -118,10 +117,10 @@ struct BitfieldInfo {
};
ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() {
- if (!m_clang_ast_importer_ap) {
- m_clang_ast_importer_ap.reset(new ClangASTImporter);
+ if (!m_clang_ast_importer_up) {
+ m_clang_ast_importer_up.reset(new ClangASTImporter);
}
- return *m_clang_ast_importer_ap;
+ return *m_clang_ast_importer_up;
}
/// Detect a forward declaration that is nested in a DW_TAG_module.
@@ -156,8 +155,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
// Since this this type is defined in one of the Clang modules imported by
// this symbol file, search all of them.
- auto *sym_file = die.GetCU()->GetSymbolFileDWARF();
- for (const auto &name_module : sym_file->getExternalTypeModules()) {
+ auto &sym_file = die.GetCU()->GetSymbolFileDWARF();
+ for (const auto &name_module : sym_file.getExternalTypeModules()) {
if (!name_module.second)
continue;
SymbolVendor *sym_vendor = name_module.second->GetSymbolVendor();
@@ -186,7 +185,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
SymbolFileDWARF *dwarf = die.GetDWARF();
TypeSP type_sp(new Type(
die.GetID(), dwarf, dwo_type_sp->GetName(), dwo_type_sp->GetByteSize(),
- NULL, LLDB_INVALID_UID, Type::eEncodingInvalid,
+ nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid,
&dwo_type_sp->GetDeclaration(), type, Type::eResolveStateForward));
dwarf->GetTypeList()->Insert(type_sp);
@@ -229,1676 +228,1454 @@ static void CompleteExternalTagDeclType(ClangASTImporter &ast_importer,
}
}
+namespace {
+/// Parsed form of all attributes that are relevant for type reconstruction.
+/// Some attributes are relevant for all kinds of types (declaration), while
+/// others are only meaningful to a specific type (is_virtual)
+struct ParsedTypeAttributes {
+ explicit ParsedTypeAttributes(const DWARFDIE &die);
+
+ AccessType accessibility = eAccessNone;
+ bool is_artificial = false;
+ bool is_complete_objc_class = false;
+ bool is_explicit = false;
+ bool is_forward_declaration = false;
+ bool is_inline = false;
+ bool is_scoped_enum = false;
+ bool is_vector = false;
+ bool is_virtual = false;
+ clang::StorageClass storage = clang::SC_None;
+ const char *mangled_name = nullptr;
+ ConstString name;
+ Declaration decl;
+ DWARFDIE object_pointer;
+ DWARFFormValue abstract_origin;
+ DWARFFormValue containing_type;
+ DWARFFormValue signature;
+ DWARFFormValue specification;
+ DWARFFormValue type;
+ LanguageType class_language = eLanguageTypeUnknown;
+ llvm::Optional<uint64_t> byte_size;
+ size_t calling_convention = llvm::dwarf::DW_CC_normal;
+ uint32_t bit_stride = 0;
+ uint32_t byte_stride = 0;
+ uint32_t encoding = 0;
+};
+} // namespace
+
+ParsedTypeAttributes::ParsedTypeAttributes(const DWARFDIE &die) {
+ DWARFAttributes attributes;
+ size_t num_attributes = die.GetAttributes(attributes);
+ for (size_t i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ if (!attributes.ExtractFormValueAtIndex(i, form_value))
+ continue;
+ switch (attr) {
+ case DW_AT_abstract_origin:
+ abstract_origin = form_value;
+ break;
+
+ case DW_AT_accessibility:
+ accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
+ break;
+
+ case DW_AT_artificial:
+ is_artificial = form_value.Boolean();
+ break;
+
+ case DW_AT_bit_stride:
+ bit_stride = form_value.Unsigned();
+ break;
+
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ break;
+
+ case DW_AT_byte_stride:
+ byte_stride = form_value.Unsigned();
+ break;
+
+ case DW_AT_calling_convention:
+ calling_convention = form_value.Unsigned();
+ break;
+
+ case DW_AT_containing_type:
+ containing_type = form_value;
+ break;
+
+ case DW_AT_decl_file:
+ decl.SetFile(die.GetCU()->GetFile(form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
+
+ case DW_AT_declaration:
+ is_forward_declaration = form_value.Boolean();
+ break;
+
+ case DW_AT_encoding:
+ encoding = form_value.Unsigned();
+ break;
+
+ case DW_AT_enum_class:
+ is_scoped_enum = form_value.Boolean();
+ break;
+
+ case DW_AT_explicit:
+ is_explicit = form_value.Boolean();
+ break;
+
+ case DW_AT_external:
+ if (form_value.Unsigned())
+ storage = clang::SC_Extern;
+ break;
+
+ case DW_AT_inline:
+ is_inline = form_value.Boolean();
+ break;
+
+ case DW_AT_linkage_name:
+ case DW_AT_MIPS_linkage_name:
+ mangled_name = form_value.AsCString();
+ break;
+
+ case DW_AT_name:
+ name.SetCString(form_value.AsCString());
+ break;
+
+ case DW_AT_object_pointer:
+ object_pointer = form_value.Reference();
+ break;
+
+ case DW_AT_signature:
+ signature = form_value;
+ break;
+
+ case DW_AT_specification:
+ specification = form_value;
+ break;
+
+ case DW_AT_type:
+ type = form_value;
+ break;
+
+ case DW_AT_virtuality:
+ is_virtual = form_value.Boolean();
+ break;
+
+ case DW_AT_APPLE_objc_complete_type:
+ is_complete_objc_class = form_value.Signed();
+ break;
+
+ case DW_AT_APPLE_runtime_class:
+ class_language = (LanguageType)form_value.Signed();
+ break;
+
+ case DW_AT_GNU_vector:
+ is_vector = form_value.Boolean();
+ break;
+ }
+ }
+}
+
+static std::string GetUnitName(const DWARFDIE &die) {
+ if (DWARFUnit *unit = die.GetCU())
+ return unit->GetAbsolutePath().GetPath();
+ return "<missing DWARF unit path>";
+}
+
TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
const DWARFDIE &die, Log *log,
bool *type_is_new_ptr) {
- TypeSP type_sp;
-
if (type_is_new_ptr)
*type_is_new_ptr = false;
- AccessType accessibility = eAccessNone;
- if (die) {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- if (log) {
- DWARFDIE context_die;
- clang::DeclContext *context =
- GetClangDeclContextContainingDIE(die, &context_die);
-
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die "
- "0x%8.8x)) %s name = '%s')",
- die.GetOffset(), static_cast<void *>(context),
- context_die.GetOffset(), die.GetTagAsCString(), die.GetName());
+ if (!die)
+ return nullptr;
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ if (log) {
+ DWARFDIE context_die;
+ clang::DeclContext *context =
+ GetClangDeclContextContainingDIE(die, &context_die);
+
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die "
+ "0x%8.8x)) %s name = '%s')",
+ die.GetOffset(), static_cast<void *>(context), context_die.GetOffset(),
+ die.GetTagAsCString(), die.GetName());
+ }
+
+
+ Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
+ if (type_ptr == DIE_IS_BEING_PARSED)
+ return nullptr;
+ if (type_ptr)
+ return type_ptr->shared_from_this();
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ ParsedTypeAttributes attrs(die);
+
+ if (DWARFDIE signature_die = attrs.signature.Reference()) {
+ if (TypeSP type_sp =
+ ParseTypeFromDWARF(sc, signature_die, log, type_is_new_ptr)) {
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ if (clang::DeclContext *decl_ctx =
+ GetCachedClangDeclContextForDIE(signature_die))
+ LinkDeclContextToDIE(decl_ctx, die);
+ return type_sp;
}
- Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
- TypeList *type_list = dwarf->GetTypeList();
- if (type_ptr == NULL) {
- if (type_is_new_ptr)
- *type_is_new_ptr = true;
+ return nullptr;
+ }
- const dw_tag_t tag = die.Tag();
+ TypeList *type_list = dwarf->GetTypeList();
+ if (type_is_new_ptr)
+ *type_is_new_ptr = true;
- bool is_forward_declaration = false;
- DWARFAttributes attributes;
- const char *type_name_cstr = NULL;
- const char *mangled_name_cstr = NULL;
- ConstString type_name_const_str;
- Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
- uint64_t byte_size = 0;
- Declaration decl;
-
- Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
- CompilerType clang_type;
- DWARFFormValue form_value;
+ const dw_tag_t tag = die.Tag();
- dw_attr_t attr;
-
- switch (tag) {
- case DW_TAG_typedef:
- case DW_TAG_base_type:
- case DW_TAG_pointer_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_const_type:
- case DW_TAG_restrict_type:
- case DW_TAG_volatile_type:
- case DW_TAG_unspecified_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- const size_t num_attributes = die.GetAttributes(attributes);
- uint32_t encoding = 0;
- DWARFFormValue encoding_uid;
-
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
- break;
- case DW_AT_decl_line:
- decl.SetLine(form_value.Unsigned());
- break;
- case DW_AT_decl_column:
- decl.SetColumn(form_value.Unsigned());
- break;
- case DW_AT_name:
- type_name_cstr = form_value.AsCString();
- if (type_name_cstr)
- type_name_const_str.SetCString(type_name_cstr);
- break;
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- break;
- case DW_AT_encoding:
- encoding = form_value.Unsigned();
- break;
- case DW_AT_type:
- encoding_uid = form_value;
- break;
- default:
- case DW_AT_sibling:
- break;
- }
- }
- }
- }
+ Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
- if (tag == DW_TAG_typedef && encoding_uid.IsValid()) {
- // Try to parse a typedef from the DWO file first as modules can
- // contain typedef'ed structures that have no names like:
- //
- // typedef struct { int a; } Foo;
- //
- // In this case we will have a structure with no name and a typedef
- // named "Foo" that points to this unnamed structure. The name in the
- // typedef is the only identifier for the struct, so always try to
- // get typedefs from DWO files if possible.
- //
- // The type_sp returned will be empty if the typedef doesn't exist in
- // a DWO file, so it is cheap to call this function just to check.
- //
- // If we don't do this we end up creating a TypeSP that says this is
- // a typedef to type 0x123 (the DW_AT_type value would be 0x123 in
- // the DW_TAG_typedef), and this is the unnamed structure type. We
- // will have a hard time tracking down an unnammed structure type in
- // the module DWO file, so we make sure we don't get into this
- // situation by always resolving typedefs from the DWO file.
- const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
-
- // First make sure that the die that this is typedef'ed to _is_ just
- // a declaration (DW_AT_declaration == 1), not a full definition
- // since template types can't be represented in modules since only
- // concrete instances of templates are ever emitted and modules won't
- // contain those
- if (encoding_die &&
- encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) ==
- 1) {
- type_sp = ParseTypeFromDWO(die, log);
- if (type_sp)
- return type_sp;
- }
- }
+ Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
+ CompilerType clang_type;
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n",
- die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr,
- encoding_uid.Reference());
+ TypeSP type_sp;
+ LanguageType cu_language = die.GetLanguage();
+ switch (tag) {
+ case DW_TAG_typedef:
+ case DW_TAG_base_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_const_type:
+ case DW_TAG_restrict_type:
+ case DW_TAG_volatile_type:
+ case DW_TAG_unspecified_type: {
+ if (tag == DW_TAG_typedef && attrs.type.IsValid()) {
+ // Try to parse a typedef from the DWO file first as modules can
+ // contain typedef'ed structures that have no names like:
+ //
+ // typedef struct { int a; } Foo;
+ //
+ // In this case we will have a structure with no name and a typedef
+ // named "Foo" that points to this unnamed structure. The name in the
+ // typedef is the only identifier for the struct, so always try to
+ // get typedefs from DWO files if possible.
+ //
+ // The type_sp returned will be empty if the typedef doesn't exist in
+ // a DWO file, so it is cheap to call this function just to check.
+ //
+ // If we don't do this we end up creating a TypeSP that says this is
+ // a typedef to type 0x123 (the DW_AT_type value would be 0x123 in
+ // the DW_TAG_typedef), and this is the unnamed structure type. We
+ // will have a hard time tracking down an unnammed structure type in
+ // the module DWO file, so we make sure we don't get into this
+ // situation by always resolving typedefs from the DWO file.
+ const DWARFDIE encoding_die = attrs.type.Reference();
+
+ // First make sure that the die that this is typedef'ed to _is_ just
+ // a declaration (DW_AT_declaration == 1), not a full definition
+ // since template types can't be represented in modules since only
+ // concrete instances of templates are ever emitted and modules won't
+ // contain those
+ if (encoding_die &&
+ encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) {
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+ }
+ }
- switch (tag) {
- default:
- break;
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n",
+ die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr,
+ encoding_uid.Reference());
- case DW_TAG_unspecified_type:
- if (strcmp(type_name_cstr, "nullptr_t") == 0 ||
- strcmp(type_name_cstr, "decltype(nullptr)") == 0) {
- resolve_state = Type::eResolveStateFull;
- clang_type = m_ast.GetBasicType(eBasicTypeNullPtr);
- break;
- }
- // Fall through to base type below in case we can handle the type
- // there...
- LLVM_FALLTHROUGH;
-
- case DW_TAG_base_type:
- resolve_state = Type::eResolveStateFull;
- clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
- type_name_cstr, encoding, byte_size * 8);
- break;
+ switch (tag) {
+ default:
+ break;
- case DW_TAG_pointer_type:
- encoding_data_type = Type::eEncodingIsPointerUID;
- break;
- case DW_TAG_reference_type:
- encoding_data_type = Type::eEncodingIsLValueReferenceUID;
- break;
- case DW_TAG_rvalue_reference_type:
- encoding_data_type = Type::eEncodingIsRValueReferenceUID;
- break;
- case DW_TAG_typedef:
- encoding_data_type = Type::eEncodingIsTypedefUID;
- break;
- case DW_TAG_const_type:
- encoding_data_type = Type::eEncodingIsConstUID;
- break;
- case DW_TAG_restrict_type:
- encoding_data_type = Type::eEncodingIsRestrictUID;
- break;
- case DW_TAG_volatile_type:
- encoding_data_type = Type::eEncodingIsVolatileUID;
- break;
- }
+ case DW_TAG_unspecified_type:
+ if (attrs.name == "nullptr_t" || attrs.name == "decltype(nullptr)") {
+ resolve_state = Type::eResolveStateFull;
+ clang_type = m_ast.GetBasicType(eBasicTypeNullPtr);
+ break;
+ }
+ // Fall through to base type below in case we can handle the type
+ // there...
+ LLVM_FALLTHROUGH;
+
+ case DW_TAG_base_type:
+ resolve_state = Type::eResolveStateFull;
+ clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
+ attrs.name.GetCString(), attrs.encoding,
+ attrs.byte_size.getValueOr(0) * 8);
+ break;
- if (!clang_type &&
- (encoding_data_type == Type::eEncodingIsPointerUID ||
- encoding_data_type == Type::eEncodingIsTypedefUID)) {
- if (tag == DW_TAG_pointer_type) {
- DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);
-
- if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0)) {
- // Blocks have a __FuncPtr inside them which is a pointer to a
- // function of the proper type.
-
- for (DWARFDIE child_die = target_die.GetFirstChild();
- child_die.IsValid(); child_die = child_die.GetSibling()) {
- if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""),
- "__FuncPtr")) {
- DWARFDIE function_pointer_type =
- child_die.GetReferencedDIE(DW_AT_type);
-
- if (function_pointer_type) {
- DWARFDIE function_type =
- function_pointer_type.GetReferencedDIE(DW_AT_type);
-
- bool function_type_is_new_pointer;
- TypeSP lldb_function_type_sp = ParseTypeFromDWARF(
- sc, function_type, log, &function_type_is_new_pointer);
-
- if (lldb_function_type_sp) {
- clang_type = m_ast.CreateBlockPointerType(
- lldb_function_type_sp->GetForwardCompilerType());
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
- }
- }
+ case DW_TAG_pointer_type:
+ encoding_data_type = Type::eEncodingIsPointerUID;
+ break;
+ case DW_TAG_reference_type:
+ encoding_data_type = Type::eEncodingIsLValueReferenceUID;
+ break;
+ case DW_TAG_rvalue_reference_type:
+ encoding_data_type = Type::eEncodingIsRValueReferenceUID;
+ break;
+ case DW_TAG_typedef:
+ encoding_data_type = Type::eEncodingIsTypedefUID;
+ break;
+ case DW_TAG_const_type:
+ encoding_data_type = Type::eEncodingIsConstUID;
+ break;
+ case DW_TAG_restrict_type:
+ encoding_data_type = Type::eEncodingIsRestrictUID;
+ break;
+ case DW_TAG_volatile_type:
+ encoding_data_type = Type::eEncodingIsVolatileUID;
+ break;
+ }
- break;
+ if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID ||
+ encoding_data_type == Type::eEncodingIsTypedefUID)) {
+ if (tag == DW_TAG_pointer_type) {
+ DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);
+
+ if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0)) {
+ // Blocks have a __FuncPtr inside them which is a pointer to a
+ // function of the proper type.
+
+ for (DWARFDIE child_die = target_die.GetFirstChild();
+ child_die.IsValid(); child_die = child_die.GetSibling()) {
+ if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""),
+ "__FuncPtr")) {
+ DWARFDIE function_pointer_type =
+ child_die.GetReferencedDIE(DW_AT_type);
+
+ if (function_pointer_type) {
+ DWARFDIE function_type =
+ function_pointer_type.GetReferencedDIE(DW_AT_type);
+
+ bool function_type_is_new_pointer;
+ TypeSP lldb_function_type_sp = ParseTypeFromDWARF(
+ sc, function_type, log, &function_type_is_new_pointer);
+
+ if (lldb_function_type_sp) {
+ clang_type = m_ast.CreateBlockPointerType(
+ lldb_function_type_sp->GetForwardCompilerType());
+ encoding_data_type = Type::eEncodingIsUID;
+ attrs.type.Clear();
+ resolve_state = Type::eResolveStateFull;
}
}
+
+ break;
}
}
+ }
+ }
- bool translation_unit_is_objc =
- (sc.comp_unit->GetLanguage() == eLanguageTypeObjC ||
- sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
+ if (cu_language == eLanguageTypeObjC ||
+ cu_language == eLanguageTypeObjC_plus_plus) {
+ if (attrs.name) {
+ static ConstString g_objc_type_name_id("id");
+ static ConstString g_objc_type_name_Class("Class");
+ static ConstString g_objc_type_name_selector("SEL");
- if (translation_unit_is_objc) {
- if (type_name_cstr != NULL) {
- static ConstString g_objc_type_name_id("id");
- static ConstString g_objc_type_name_Class("Class");
- static ConstString g_objc_type_name_selector("SEL");
+ if (attrs.name == g_objc_type_name_id) {
+ if (log)
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
+ "is Objective-C 'id' built-in type.",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
+ clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
+ encoding_data_type = Type::eEncodingIsUID;
+ attrs.type.Clear();
+ resolve_state = Type::eResolveStateFull;
- if (type_name_const_str == g_objc_type_name_id) {
- if (log)
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
- "is Objective-C 'id' built-in type.",
- die.GetOffset(), die.GetTagAsCString(), die.GetName());
- clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
+ } else if (attrs.name == g_objc_type_name_Class) {
+ if (log)
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
+ "is Objective-C 'Class' built-in type.",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
+ clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
+ encoding_data_type = Type::eEncodingIsUID;
+ attrs.type.Clear();
+ resolve_state = Type::eResolveStateFull;
+ } else if (attrs.name == g_objc_type_name_selector) {
+ if (log)
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
+ "is Objective-C 'selector' built-in type.",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
+ clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
+ encoding_data_type = Type::eEncodingIsUID;
+ attrs.type.Clear();
+ resolve_state = Type::eResolveStateFull;
+ }
+ } else if (encoding_data_type == Type::eEncodingIsPointerUID &&
+ attrs.type.IsValid()) {
+ // Clang sometimes erroneously emits id as objc_object*. In that
+ // case we fix up the type to "id".
- } else if (type_name_const_str == g_objc_type_name_Class) {
- if (log)
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
- "is Objective-C 'Class' built-in type.",
- die.GetOffset(), die.GetTagAsCString(), die.GetName());
- clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
- } else if (type_name_const_str == g_objc_type_name_selector) {
+ const DWARFDIE encoding_die = attrs.type.Reference();
+
+ if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) {
+ if (const char *struct_name = encoding_die.GetName()) {
+ if (!strcmp(struct_name, "objc_object")) {
if (log)
dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
- "is Objective-C 'selector' built-in type.",
+ log,
+ "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s "
+ "'%s' is 'objc_object*', which we overrode to "
+ "'id'.",
die.GetOffset(), die.GetTagAsCString(), die.GetName());
- clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
+ clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
+ attrs.type.Clear();
resolve_state = Type::eResolveStateFull;
}
- } else if (encoding_data_type == Type::eEncodingIsPointerUID &&
- encoding_uid.IsValid()) {
- // Clang sometimes erroneously emits id as objc_object*. In that
- // case we fix up the type to "id".
-
- const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
-
- if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) {
- if (const char *struct_name = encoding_die.GetName()) {
- if (!strcmp(struct_name, "objc_object")) {
- if (log)
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s "
- "'%s' is 'objc_object*', which we overrode to "
- "'id'.",
- die.GetOffset(), die.GetTagAsCString(),
- die.GetName());
- clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
- }
- }
- }
}
}
}
+ }
+ }
- type_sp.reset(
- new Type(die.GetID(), dwarf, type_name_const_str, byte_size, NULL,
- DIERef(encoding_uid).GetUID(dwarf), encoding_data_type,
- &decl, clang_type, resolve_state));
+ type_sp = std::make_shared<Type>(
+ die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
+ dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl,
+ clang_type, resolve_state);
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- } break;
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ } break;
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
- bool byte_size_valid = false;
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type: {
+ // UniqueDWARFASTType is large, so don't create a local variables on
+ // the stack, put it on the heap. This function is often called
+ // recursively and clang isn't good and sharing the stack space for
+ // variables in different blocks.
+ std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_up(
+ new UniqueDWARFASTType());
+
+ ConstString unique_typename(attrs.name);
+ Declaration unique_decl(attrs.decl);
+
+ if (attrs.name) {
+ if (Language::LanguageIsCPlusPlus(cu_language)) {
+ // For C++, we rely solely upon the one definition rule that says
+ // only one thing can exist at a given decl context. We ignore the
+ // file and line that things are declared on.
+ std::string qualified_name;
+ if (die.GetQualifiedName(qualified_name))
+ unique_typename = ConstString(qualified_name);
+ unique_decl.Clear();
+ }
- LanguageType class_language = eLanguageTypeUnknown;
- bool is_complete_objc_class = false;
- size_t calling_convention
- = llvm::dwarf::CallingConvention::DW_CC_normal;
-
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
- break;
-
- case DW_AT_decl_line:
- decl.SetLine(form_value.Unsigned());
- break;
-
- case DW_AT_decl_column:
- decl.SetColumn(form_value.Unsigned());
- break;
-
- case DW_AT_name:
- type_name_cstr = form_value.AsCString();
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- byte_size_valid = true;
- break;
-
- case DW_AT_accessibility:
- accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
- break;
-
- case DW_AT_declaration:
- is_forward_declaration = form_value.Boolean();
- break;
-
- case DW_AT_APPLE_runtime_class:
- class_language = (LanguageType)form_value.Signed();
- break;
-
- case DW_AT_APPLE_objc_complete_type:
- is_complete_objc_class = form_value.Signed();
- break;
- case DW_AT_calling_convention:
- calling_convention = form_value.Unsigned();
- break;
-
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_data_location:
- case DW_AT_description:
- case DW_AT_start_scope:
- case DW_AT_visibility:
- default:
- case DW_AT_sibling:
- break;
- }
- }
- }
+ if (dwarf->GetUniqueDWARFASTTypeMap().Find(
+ unique_typename, die, unique_decl, attrs.byte_size.getValueOr(-1),
+ *unique_ast_entry_up)) {
+ type_sp = unique_ast_entry_up->m_type_sp;
+ if (type_sp) {
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
}
+ }
+ }
- // UniqueDWARFASTType is large, so don't create a local variables on
- // the stack, put it on the heap. This function is often called
- // recursively and clang isn't good and sharing the stack space for
- // variables in different blocks.
- std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(
- new UniqueDWARFASTType());
-
- ConstString unique_typename(type_name_const_str);
- Declaration unique_decl(decl);
-
- if (type_name_const_str) {
- LanguageType die_language = die.GetLanguage();
- if (Language::LanguageIsCPlusPlus(die_language)) {
- // For C++, we rely solely upon the one definition rule that says
- // only one thing can exist at a given decl context. We ignore the
- // file and line that things are declared on.
- std::string qualified_name;
- if (die.GetQualifiedName(qualified_name))
- unique_typename = ConstString(qualified_name);
- unique_decl.Clear();
- }
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+
+ int tag_decl_kind = -1;
+ AccessType default_accessibility = eAccessNone;
+ if (tag == DW_TAG_structure_type) {
+ tag_decl_kind = clang::TTK_Struct;
+ default_accessibility = eAccessPublic;
+ } else if (tag == DW_TAG_union_type) {
+ tag_decl_kind = clang::TTK_Union;
+ default_accessibility = eAccessPublic;
+ } else if (tag == DW_TAG_class_type) {
+ tag_decl_kind = clang::TTK_Class;
+ default_accessibility = eAccessPrivate;
+ }
- if (dwarf->GetUniqueDWARFASTTypeMap().Find(
- unique_typename, die, unique_decl,
- byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) {
- type_sp = unique_ast_entry_ap->m_type_sp;
- if (type_sp) {
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
+ if (attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
+ !die.HasChildren() && cu_language == eLanguageTypeObjC) {
+ // Work around an issue with clang at the moment where forward
+ // declarations for objective C classes are emitted as:
+ // DW_TAG_structure_type [2]
+ // DW_AT_name( "ForwardObjcClass" )
+ // DW_AT_byte_size( 0x00 )
+ // DW_AT_decl_file( "..." )
+ // DW_AT_decl_line( 1 )
+ //
+ // Note that there is no DW_AT_declaration and there are no children,
+ // and the byte size is zero.
+ attrs.is_forward_declaration = true;
+ }
+
+ if (attrs.class_language == eLanguageTypeObjC ||
+ attrs.class_language == eLanguageTypeObjC_plus_plus) {
+ if (!attrs.is_complete_objc_class &&
+ die.Supports_DW_AT_APPLE_objc_complete_type()) {
+ // We have a valid eSymbolTypeObjCClass class symbol whose name
+ // matches the current objective C class that we are trying to find
+ // and this DIE isn't the complete definition (we checked
+ // is_complete_objc_class above and know it is false), so the real
+ // definition is in here somewhere
+ type_sp =
+ dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF,
+ // see if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
+ die, attrs.name, true);
}
}
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
-
- int tag_decl_kind = -1;
- AccessType default_accessibility = eAccessNone;
- if (tag == DW_TAG_structure_type) {
- tag_decl_kind = clang::TTK_Struct;
- default_accessibility = eAccessPublic;
- } else if (tag == DW_TAG_union_type) {
- tag_decl_kind = clang::TTK_Union;
- default_accessibility = eAccessPublic;
- } else if (tag == DW_TAG_class_type) {
- tag_decl_kind = clang::TTK_Class;
- default_accessibility = eAccessPrivate;
- }
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an "
+ "incomplete objc type, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+ type_sp->GetID());
+ }
- if (byte_size_valid && byte_size == 0 && type_name_cstr &&
- !die.HasChildren() &&
- sc.comp_unit->GetLanguage() == eLanguageTypeObjC) {
- // Work around an issue with clang at the moment where forward
- // declarations for objective C classes are emitted as:
- // DW_TAG_structure_type [2]
- // DW_AT_name( "ForwardObjcClass" )
- // DW_AT_byte_size( 0x00 )
- // DW_AT_decl_file( "..." )
- // DW_AT_decl_line( 1 )
- //
- // Note that there is no DW_AT_declaration and there are no children,
- // and the byte size is zero.
- is_forward_declaration = true;
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this
+ // die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
}
+ }
+ }
- if (class_language == eLanguageTypeObjC ||
- class_language == eLanguageTypeObjC_plus_plus) {
- if (!is_complete_objc_class &&
- die.Supports_DW_AT_APPLE_objc_complete_type()) {
- // We have a valid eSymbolTypeObjCClass class symbol whose name
- // matches the current objective C class that we are trying to find
- // and this DIE isn't the complete definition (we checked
- // is_complete_objc_class above and know it is false), so the real
- // definition is in here somewhere
- type_sp = dwarf->FindCompleteObjCDefinitionTypeForDIE(
- die, type_name_const_str, true);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF,
- // see if we have a declaration anywhere else...
- type_sp =
- debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
- die, type_name_const_str, true);
- }
- }
+ if (attrs.is_forward_declaration) {
+ // We have a forward declaration to a type and we need to try and
+ // find a full declaration. We look in the current type index just in
+ // case we have a forward declaration followed by an actual
+ // declarations in the DWARF. If this fails, we need to look
+ // elsewhere...
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, trying to find complete type",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString());
+ }
- if (type_sp) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an "
- "incomplete objc type, complete type is 0x%8.8" PRIx64,
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), type_name_cstr,
- type_sp->GetID());
- }
+ // See if the type comes from a DWO module and if so, track down that
+ // type.
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+
+ DWARFDeclContext die_decl_ctx;
+ die.GetDWARFDeclContext(die_decl_ctx);
+
+ // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
+ // type_name_const_str);
+ type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF, see
+ // if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
+ die_decl_ctx);
+ }
+ }
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this
- // die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+ type_sp->GetID());
}
- if (is_forward_declaration) {
- // We have a forward declaration to a type and we need to try and
- // find a full declaration. We look in the current type index just in
- // case we have a forward declaration followed by an actual
- // declarations in the DWARF. If this fails, we need to look
- // elsewhere...
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
- "forward declaration, trying to find complete type",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), type_name_cstr);
- }
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::DeclContext *defn_decl_ctx =
+ GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
+ if (defn_decl_ctx)
+ LinkDeclContextToDIE(defn_decl_ctx, die);
+ return type_sp;
+ }
+ }
+ assert(tag_decl_kind != -1);
+ bool clang_type_was_created = false;
+ clang_type.SetCompilerType(
+ &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ if (!clang_type) {
+ clang::DeclContext *decl_ctx =
+ GetClangDeclContextContainingDIE(die, nullptr);
- // See if the type comes from a DWO module and if so, track down that
- // type.
- type_sp = ParseTypeFromDWO(die, log);
- if (type_sp)
- return type_sp;
-
- DWARFDeclContext die_decl_ctx;
- die.GetDWARFDeclContext(die_decl_ctx);
-
- // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
- // type_name_const_str);
- type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF, see
- // if we have a declaration anywhere else...
- type_sp =
- debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
- die_decl_ctx);
- }
- }
+ // If your decl context is a record that was imported from another
+ // AST context (in the gmodules case), we need to make sure the type
+ // backing the Decl is complete before adding children to it. This is
+ // not an issue in the non-gmodules case because the debug info will
+ // always contain a full definition of parent types in that case.
+ CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
+ attrs.name.GetCString());
+
+ if (attrs.accessibility == eAccessNone && decl_ctx) {
+ // Check the decl context that contains this class/struct/union. If
+ // it is a class we must give it an accessibility.
+ const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
+ if (DeclKindIsCXXClass(containing_decl_kind))
+ attrs.accessibility = default_accessibility;
+ }
- if (type_sp) {
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+ metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
+
+ if (attrs.name.GetStringRef().contains('<')) {
+ ClangASTContext::TemplateParameterInfos template_param_infos;
+ if (ParseTemplateParameterInfos(die, template_param_infos)) {
+ clang::ClassTemplateDecl *class_template_decl =
+ m_ast.ParseClassTemplateDecl(decl_ctx, attrs.accessibility,
+ attrs.name.GetCString(),
+ tag_decl_kind, template_param_infos);
+ if (!class_template_decl) {
if (log) {
dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
- "forward declaration, complete type is 0x%8.8" PRIx64,
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
+ "clang::ClassTemplateDecl failed to return a decl.",
static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), type_name_cstr, type_sp->GetID());
+ DW_TAG_value_to_name(tag), attrs.name.GetCString());
}
-
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
- dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf)));
- if (defn_decl_ctx)
- LinkDeclContextToDIE(defn_decl_ctx, die);
- return type_sp;
- }
- }
- assert(tag_decl_kind != -1);
- bool clang_type_was_created = false;
- clang_type.SetCompilerType(
- &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
- if (!clang_type) {
- clang::DeclContext *decl_ctx =
- GetClangDeclContextContainingDIE(die, nullptr);
-
- // If your decl context is a record that was imported from another
- // AST context (in the gmodules case), we need to make sure the type
- // backing the Decl is complete before adding children to it. This is
- // not an issue in the non-gmodules case because the debug info will
- // always contain a full definition of parent types in that case.
- CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
- type_name_cstr);
-
- if (accessibility == eAccessNone && decl_ctx) {
- // Check the decl context that contains this class/struct/union. If
- // it is a class we must give it an accessibility.
- const clang::Decl::Kind containing_decl_kind =
- decl_ctx->getDeclKind();
- if (DeclKindIsCXXClass(containing_decl_kind))
- accessibility = default_accessibility;
+ return TypeSP();
}
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
- metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
-
- if (type_name_cstr && strchr(type_name_cstr, '<')) {
- ClangASTContext::TemplateParameterInfos template_param_infos;
- if (ParseTemplateParameterInfos(die, template_param_infos)) {
- clang::ClassTemplateDecl *class_template_decl =
- m_ast.ParseClassTemplateDecl(decl_ctx, accessibility,
- type_name_cstr, tag_decl_kind,
- template_param_infos);
- if (!class_template_decl) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
- "clang::ClassTemplateDecl failed to return a decl.",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), type_name_cstr);
- }
- return TypeSP();
- }
-
- clang::ClassTemplateSpecializationDecl
- *class_specialization_decl =
- m_ast.CreateClassTemplateSpecializationDecl(
- decl_ctx, class_template_decl, tag_decl_kind,
- template_param_infos);
- clang_type = m_ast.CreateClassTemplateSpecializationType(
- class_specialization_decl);
- clang_type_was_created = true;
-
- m_ast.SetMetadata(class_template_decl, metadata);
- m_ast.SetMetadata(class_specialization_decl, metadata);
- }
- }
+ clang::ClassTemplateSpecializationDecl *class_specialization_decl =
+ m_ast.CreateClassTemplateSpecializationDecl(
+ decl_ctx, class_template_decl, tag_decl_kind,
+ template_param_infos);
+ clang_type = m_ast.CreateClassTemplateSpecializationType(
+ class_specialization_decl);
+ clang_type_was_created = true;
- if (!clang_type_was_created) {
- clang_type_was_created = true;
- clang_type = m_ast.CreateRecordType(decl_ctx, accessibility,
- type_name_cstr, tag_decl_kind,
- class_language, &metadata);
- }
- }
-
- // Store a forward declaration to this class type in case any
- // parameters in any class methods need it for the clang types for
- // function prototypes.
- LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
- type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
- byte_size, NULL, LLDB_INVALID_UID,
- Type::eEncodingIsUID, &decl, clang_type,
- Type::eResolveStateForward));
-
- type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
-
- // Add our type to the unique type map so we don't end up creating many
- // copies of the same type over and over in the ASTContext for our
- // module
- unique_ast_entry_ap->m_type_sp = type_sp;
- unique_ast_entry_ap->m_die = die;
- unique_ast_entry_ap->m_declaration = unique_decl;
- unique_ast_entry_ap->m_byte_size = byte_size;
- dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
- *unique_ast_entry_ap);
-
- if (is_forward_declaration && die.HasChildren()) {
- // Check to see if the DIE actually has a definition, some version of
- // GCC will
- // emit DIEs with DW_AT_declaration set to true, but yet still have
- // subprogram, members, or inheritance, so we can't trust it
- DWARFDIE child_die = die.GetFirstChild();
- while (child_die) {
- switch (child_die.Tag()) {
- case DW_TAG_inheritance:
- case DW_TAG_subprogram:
- case DW_TAG_member:
- case DW_TAG_APPLE_property:
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- child_die.Clear();
- is_forward_declaration = false;
- break;
- default:
- child_die = child_die.GetSibling();
- break;
- }
- }
+ m_ast.SetMetadata(class_template_decl, metadata);
+ m_ast.SetMetadata(class_specialization_decl, metadata);
}
+ }
- if (!is_forward_declaration) {
- // Always start the definition for a class type so that if the class
- // has child classes or types that require the class to be created
- // for use as their decl contexts the class will be ready to accept
- // these child definitions.
- if (!die.HasChildren()) {
- // No children for this struct/union/class, lets finish it
- if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
- ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
- } else {
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
- "definition.\nPlease file a bug and attach the file at the "
- "start of this error message",
- die.GetOffset(), type_name_cstr);
- }
+ if (!clang_type_was_created) {
+ clang_type_was_created = true;
+ clang_type = m_ast.CreateRecordType(
+ decl_ctx, attrs.accessibility, attrs.name.GetCString(),
+ tag_decl_kind, attrs.class_language, &metadata);
+ }
+ }
- if (tag == DW_TAG_structure_type) // this only applies in C
- {
- clang::RecordDecl *record_decl =
- ClangASTContext::GetAsRecordDecl(clang_type);
+ // Store a forward declaration to this class type in case any
+ // parameters in any class methods need it for the clang types for
+ // function prototypes.
+ LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
+ type_sp = std::make_shared<Type>(die.GetID(), dwarf, attrs.name,
+ attrs.byte_size, nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, &attrs.decl, clang_type,
+ Type::eResolveStateForward);
+
+ type_sp->SetIsCompleteObjCClass(attrs.is_complete_objc_class);
+
+ // Add our type to the unique type map so we don't end up creating many
+ // copies of the same type over and over in the ASTContext for our
+ // module
+ unique_ast_entry_up->m_type_sp = type_sp;
+ unique_ast_entry_up->m_die = die;
+ unique_ast_entry_up->m_declaration = unique_decl;
+ unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0);
+ dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
+ *unique_ast_entry_up);
+
+ if (attrs.is_forward_declaration && die.HasChildren()) {
+ // Check to see if the DIE actually has a definition, some version of
+ // GCC will
+ // emit DIEs with DW_AT_declaration set to true, but yet still have
+ // subprogram, members, or inheritance, so we can't trust it
+ DWARFDIE child_die = die.GetFirstChild();
+ while (child_die) {
+ switch (child_die.Tag()) {
+ case DW_TAG_inheritance:
+ case DW_TAG_subprogram:
+ case DW_TAG_member:
+ case DW_TAG_APPLE_property:
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_typedef:
+ case DW_TAG_union_type:
+ child_die.Clear();
+ attrs.is_forward_declaration = false;
+ break;
+ default:
+ child_die = child_die.GetSibling();
+ break;
+ }
+ }
+ }
- if (record_decl) {
- GetClangASTImporter().InsertRecordDecl(
- record_decl, ClangASTImporter::LayoutInfo());
- }
- }
- } else if (clang_type_was_created) {
- // Start the definition if the class is not objective C since the
- // underlying decls respond to isCompleteDefinition(). Objective
- // C decls don't respond to isCompleteDefinition() so we can't
- // start the declaration definition right away. For C++
- // class/union/structs we want to start the definition in case the
- // class is needed as the declaration context for a contained class
- // or type without the need to complete that type..
-
- if (class_language != eLanguageTypeObjC &&
- class_language != eLanguageTypeObjC_plus_plus)
- ClangASTContext::StartTagDeclarationDefinition(clang_type);
-
- // Leave this as a forward declaration until we need to know the
- // details of the type. lldb_private::Type will automatically call
- // the SymbolFile virtual function
- // "SymbolFileDWARF::CompleteType(Type *)" When the definition
- // needs to be defined.
- assert(!dwarf->GetForwardDeclClangTypeToDie().count(
- ClangUtil::RemoveFastQualifiers(clang_type)
- .GetOpaqueQualType()) &&
- "Type already in the forward declaration map!");
- // Can't assume m_ast.GetSymbolFile() is actually a
- // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
- // binaries.
- dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
- clang_type.GetOpaqueQualType();
- dwarf->GetForwardDeclClangTypeToDie()
- [ClangUtil::RemoveFastQualifiers(clang_type)
- .GetOpaqueQualType()] = die.GetDIERef();
- m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
- }
+ if (!attrs.is_forward_declaration) {
+ // Always start the definition for a class type so that if the class
+ // has child classes or types that require the class to be created
+ // for use as their decl contexts the class will be ready to accept
+ // these child definitions.
+ if (!die.HasChildren()) {
+ // No children for this struct/union/class, lets finish it
+ if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
+ ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
+ "definition.\nPlease file a bug and attach the file at the "
+ "start of this error message",
+ die.GetOffset(), attrs.name.GetCString());
}
-
- // If we made a clang type, set the trivial abi if applicable: We only
- // do this for pass by value - which implies the Trivial ABI. There
- // isn't a way to assert that something that would normally be pass by
- // value is pass by reference, so we ignore that attribute if set.
- if (calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
- clang::CXXRecordDecl *record_decl =
- m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+
+ if (tag == DW_TAG_structure_type) // this only applies in C
+ {
+ clang::RecordDecl *record_decl =
+ ClangASTContext::GetAsRecordDecl(clang_type);
+
if (record_decl) {
- record_decl->setHasTrivialSpecialMemberForCall();
+ GetClangASTImporter().InsertRecordDecl(
+ record_decl, ClangASTImporter::LayoutInfo());
}
}
+ } else if (clang_type_was_created) {
+ // Start the definition if the class is not objective C since the
+ // underlying decls respond to isCompleteDefinition(). Objective
+ // C decls don't respond to isCompleteDefinition() so we can't
+ // start the declaration definition right away. For C++
+ // class/union/structs we want to start the definition in case the
+ // class is needed as the declaration context for a contained class
+ // or type without the need to complete that type..
+
+ if (attrs.class_language != eLanguageTypeObjC &&
+ attrs.class_language != eLanguageTypeObjC_plus_plus)
+ ClangASTContext::StartTagDeclarationDefinition(clang_type);
- } break;
+ // Leave this as a forward declaration until we need to know the
+ // details of the type. lldb_private::Type will automatically call
+ // the SymbolFile virtual function
+ // "SymbolFileDWARF::CompleteType(Type *)" When the definition
+ // needs to be defined.
+ assert(!dwarf->GetForwardDeclClangTypeToDie().count(
+ ClangUtil::RemoveFastQualifiers(clang_type)
+ .GetOpaqueQualType()) &&
+ "Type already in the forward declaration map!");
+ // Can't assume m_ast.GetSymbolFile() is actually a
+ // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
+ // binaries.
+ dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
+ clang_type.GetOpaqueQualType();
+ dwarf->GetForwardDeclClangTypeToDie()
+ [ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] =
+ die.GetID();
+ m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
+ }
+ }
- case DW_TAG_enumeration_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+ // If we made a clang type, set the trivial abi if applicable: We only
+ // do this for pass by value - which implies the Trivial ABI. There
+ // isn't a way to assert that something that would normally be pass by
+ // value is pass by reference, so we ignore that attribute if set.
+ if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ if (record_decl) {
+ record_decl->setHasTrivialSpecialMemberForCall();
+ }
+ }
- bool is_scoped = false;
- DWARFFormValue encoding_form;
+ if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ if (record_decl)
+ record_decl->setArgPassingRestrictions(
+ clang::RecordDecl::APK_CannotPassInRegs);
+ }
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0) {
- uint32_t i;
-
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
- break;
- case DW_AT_decl_line:
- decl.SetLine(form_value.Unsigned());
- break;
- case DW_AT_decl_column:
- decl.SetColumn(form_value.Unsigned());
- break;
- case DW_AT_name:
- type_name_cstr = form_value.AsCString();
- type_name_const_str.SetCString(type_name_cstr);
- break;
- case DW_AT_type:
- encoding_form = form_value;
- break;
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- break;
- case DW_AT_accessibility:
- break; // accessibility =
- // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration:
- is_forward_declaration = form_value.Boolean();
- break;
- case DW_AT_enum_class:
- is_scoped = form_value.Boolean();
- break;
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_bit_stride:
- case DW_AT_byte_stride:
- case DW_AT_data_location:
- case DW_AT_description:
- case DW_AT_start_scope:
- case DW_AT_visibility:
- case DW_AT_specification:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
- }
- }
- }
+ } break;
- if (is_forward_declaration) {
- type_sp = ParseTypeFromDWO(die, log);
- if (type_sp)
- return type_sp;
-
- DWARFDeclContext die_decl_ctx;
- die.GetDWARFDeclContext(die_decl_ctx);
-
- type_sp =
- dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF,
- // see if we have a declaration anywhere else...
- type_sp =
- debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
- die_decl_ctx);
- }
- }
+ case DW_TAG_enumeration_type: {
+ if (attrs.is_forward_declaration) {
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
- if (type_sp) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
- "forward declaration, complete type is 0x%8.8" PRIx64,
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), type_name_cstr,
- type_sp->GetID());
- }
+ DWARFDeclContext die_decl_ctx;
+ die.GetDWARFDeclContext(die_decl_ctx);
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this
- // die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::DeclContext *defn_decl_ctx =
- GetCachedClangDeclContextForDIE(dwarf->DebugInfo()->GetDIE(
- DIERef(type_sp->GetID(), dwarf)));
- if (defn_decl_ctx)
- LinkDeclContextToDIE(defn_decl_ctx, die);
- return type_sp;
- }
- }
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
-
- CompilerType enumerator_clang_type;
- clang_type.SetCompilerType(
- &m_ast,
- dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
- if (!clang_type) {
- if (encoding_form.IsValid()) {
- Type *enumerator_type =
- dwarf->ResolveTypeUID(DIERef(encoding_form));
- if (enumerator_type)
- enumerator_clang_type = enumerator_type->GetFullCompilerType();
- }
+ type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
- if (!enumerator_clang_type) {
- if (byte_size > 0) {
- enumerator_clang_type =
- m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
- NULL, DW_ATE_signed, byte_size * 8);
- } else {
- enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
- }
- }
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF,
+ // see if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
+ die_decl_ctx);
+ }
+ }
- clang_type = m_ast.CreateEnumerationType(
- type_name_cstr, GetClangDeclContextContainingDIE(die, nullptr),
- decl, enumerator_clang_type, is_scoped);
- } else {
- enumerator_clang_type =
- m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType());
- }
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+ type_sp->GetID());
+ }
- LinkDeclContextToDIE(
- ClangASTContext::GetDeclContextForType(clang_type), die);
-
- type_sp.reset(new Type(
- die.GetID(), dwarf, type_name_const_str, byte_size, NULL,
- DIERef(encoding_form).GetUID(dwarf), Type::eEncodingIsUID, &decl,
- clang_type, Type::eResolveStateForward));
-
- if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
- if (die.HasChildren()) {
- SymbolContext cu_sc(die.GetLLDBCompileUnit());
- bool is_signed = false;
- enumerator_clang_type.IsIntegerType(is_signed);
- ParseChildEnumerators(cu_sc, clang_type, is_signed,
- type_sp->GetByteSize(), die);
- }
- ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
- } else {
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
- "definition.\nPlease file a bug and attach the file at the "
- "start of this error message",
- die.GetOffset(), type_name_cstr);
- }
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this
+ // die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::DeclContext *defn_decl_ctx =
+ GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
+ if (defn_decl_ctx)
+ LinkDeclContextToDIE(defn_decl_ctx, die);
+ return type_sp;
+ }
+ }
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+
+ CompilerType enumerator_clang_type;
+ clang_type.SetCompilerType(
+ &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ if (!clang_type) {
+ if (attrs.type.IsValid()) {
+ Type *enumerator_type =
+ dwarf->ResolveTypeUID(attrs.type.Reference(), true);
+ if (enumerator_type)
+ enumerator_clang_type = enumerator_type->GetFullCompilerType();
+ }
+
+ if (!enumerator_clang_type) {
+ if (attrs.byte_size) {
+ enumerator_clang_type =
+ m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
+ NULL, DW_ATE_signed, *attrs.byte_size * 8);
+ } else {
+ enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
}
- } break;
+ }
- case DW_TAG_inlined_subroutine:
- case DW_TAG_subprogram:
- case DW_TAG_subroutine_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+ clang_type = m_ast.CreateEnumerationType(
+ attrs.name.GetCString(),
+ GetClangDeclContextContainingDIE(die, nullptr), attrs.decl,
+ enumerator_clang_type, attrs.is_scoped_enum);
+ } else {
+ enumerator_clang_type =
+ m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType());
+ }
- DWARFFormValue type_die_form;
- bool is_variadic = false;
- bool is_inline = false;
- bool is_static = false;
- bool is_virtual = false;
- bool is_explicit = false;
- bool is_artificial = false;
- bool has_template_params = false;
- DWARFFormValue specification_die_form;
- DWARFFormValue abstract_origin_die_form;
- dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
+ LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type),
+ die);
- unsigned type_quals = 0;
- clang::StorageClass storage =
- clang::SC_None; //, Extern, Static, PrivateExtern
-
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
- break;
- case DW_AT_decl_line:
- decl.SetLine(form_value.Unsigned());
- break;
- case DW_AT_decl_column:
- decl.SetColumn(form_value.Unsigned());
- break;
- case DW_AT_name:
- type_name_cstr = form_value.AsCString();
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_linkage_name:
- case DW_AT_MIPS_linkage_name:
- mangled_name_cstr = form_value.AsCString();
- break;
- case DW_AT_type:
- type_die_form = form_value;
- break;
- case DW_AT_accessibility:
- accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
- break;
- case DW_AT_declaration:
- break; // is_forward_declaration = form_value.Boolean(); break;
- case DW_AT_inline:
- is_inline = form_value.Boolean();
- break;
- case DW_AT_virtuality:
- is_virtual = form_value.Boolean();
- break;
- case DW_AT_explicit:
- is_explicit = form_value.Boolean();
- break;
- case DW_AT_artificial:
- is_artificial = form_value.Boolean();
- break;
-
- case DW_AT_external:
- if (form_value.Unsigned()) {
- if (storage == clang::SC_None)
- storage = clang::SC_Extern;
- else
- storage = clang::SC_PrivateExtern;
- }
- break;
-
- case DW_AT_specification:
- specification_die_form = form_value;
- break;
-
- case DW_AT_abstract_origin:
- abstract_origin_die_form = form_value;
- break;
-
- case DW_AT_object_pointer:
- object_pointer_die_offset = form_value.Reference();
- break;
-
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_address_class:
- case DW_AT_calling_convention:
- case DW_AT_data_location:
- case DW_AT_elemental:
- case DW_AT_entry_pc:
- case DW_AT_frame_base:
- case DW_AT_high_pc:
- case DW_AT_low_pc:
- case DW_AT_prototyped:
- case DW_AT_pure:
- case DW_AT_ranges:
- case DW_AT_recursive:
- case DW_AT_return_addr:
- case DW_AT_segment:
- case DW_AT_start_scope:
- case DW_AT_static_link:
- case DW_AT_trampoline:
- case DW_AT_visibility:
- case DW_AT_vtable_elem_location:
- case DW_AT_description:
- case DW_AT_sibling:
- break;
- }
- }
- }
- }
+ type_sp = std::make_shared<Type>(
+ die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
+ dwarf->GetUID(attrs.type.Reference()), Type::eEncodingIsUID,
+ &attrs.decl, clang_type, Type::eResolveStateForward);
- std::string object_pointer_name;
- if (object_pointer_die_offset != DW_INVALID_OFFSET) {
- DWARFDIE object_pointer_die = die.GetDIE(object_pointer_die_offset);
- if (object_pointer_die) {
- const char *object_pointer_name_cstr = object_pointer_die.GetName();
- if (object_pointer_name_cstr)
- object_pointer_name = object_pointer_name_cstr;
- }
- }
+ if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
+ if (die.HasChildren()) {
+ bool is_signed = false;
+ enumerator_clang_type.IsIntegerType(is_signed);
+ ParseChildEnumerators(clang_type, is_signed,
+ type_sp->GetByteSize().getValueOr(0), die);
+ }
+ ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
+ "definition.\nPlease file a bug and attach the file at the "
+ "start of this error message",
+ die.GetOffset(), attrs.name.GetCString());
+ }
+ } break;
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_subprogram:
+ case DW_TAG_subroutine_type: {
+ bool is_variadic = false;
+ bool is_static = false;
+ bool has_template_params = false;
+
+ unsigned type_quals = 0;
+
+ std::string object_pointer_name;
+ if (attrs.object_pointer) {
+ const char *object_pointer_name_cstr = attrs.object_pointer.GetName();
+ if (object_pointer_name_cstr)
+ object_pointer_name = object_pointer_name_cstr;
+ }
- CompilerType return_clang_type;
- Type *func_type = NULL;
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
- if (type_die_form.IsValid())
- func_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
+ CompilerType return_clang_type;
+ Type *func_type = NULL;
- if (func_type)
- return_clang_type = func_type->GetForwardCompilerType();
- else
- return_clang_type = m_ast.GetBasicType(eBasicTypeVoid);
+ if (attrs.type.IsValid())
+ func_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true);
- std::vector<CompilerType> function_param_types;
- std::vector<clang::ParmVarDecl *> function_param_decls;
+ if (func_type)
+ return_clang_type = func_type->GetForwardCompilerType();
+ else
+ return_clang_type = m_ast.GetBasicType(eBasicTypeVoid);
- // Parse the function children for the parameters
+ std::vector<CompilerType> function_param_types;
+ std::vector<clang::ParmVarDecl *> function_param_decls;
- DWARFDIE decl_ctx_die;
- clang::DeclContext *containing_decl_ctx =
- GetClangDeclContextContainingDIE(die, &decl_ctx_die);
- const clang::Decl::Kind containing_decl_kind =
- containing_decl_ctx->getDeclKind();
-
- bool is_cxx_method = DeclKindIsCXXClass(containing_decl_kind);
- // Start off static. This will be set to false in
- // ParseChildParameters(...) if we find a "this" parameters as the
- // first parameter
- if (is_cxx_method) {
- is_static = true;
- }
+ // Parse the function children for the parameters
- if (die.HasChildren()) {
- bool skip_artificial = true;
- ParseChildParameters(*sc.comp_unit, containing_decl_ctx, die,
- skip_artificial, is_static, is_variadic,
- has_template_params, function_param_types,
- function_param_decls, type_quals);
- }
+ DWARFDIE decl_ctx_die;
+ clang::DeclContext *containing_decl_ctx =
+ GetClangDeclContextContainingDIE(die, &decl_ctx_die);
+ const clang::Decl::Kind containing_decl_kind =
+ containing_decl_ctx->getDeclKind();
- bool ignore_containing_context = false;
- // Check for templatized class member functions. If we had any
- // DW_TAG_template_type_parameter or DW_TAG_template_value_parameter
- // the DW_TAG_subprogram DIE, then we can't let this become a method in
- // a class. Why? Because templatized functions are only emitted if one
- // of the templatized methods is used in the current compile unit and
- // we will end up with classes that may or may not include these member
- // functions and this means one class won't match another class
- // definition and it affects our ability to use a class in the clang
- // expression parser. So for the greater good, we currently must not
- // allow any template member functions in a class definition.
- if (is_cxx_method && has_template_params) {
- ignore_containing_context = true;
- is_cxx_method = false;
- }
+ bool is_cxx_method = DeclKindIsCXXClass(containing_decl_kind);
+ // Start off static. This will be set to false in
+ // ParseChildParameters(...) if we find a "this" parameters as the
+ // first parameter
+ if (is_cxx_method) {
+ is_static = true;
+ }
- // clang_type will get the function prototype clang type after this
- // call
- clang_type = m_ast.CreateFunctionType(
- return_clang_type, function_param_types.data(),
- function_param_types.size(), is_variadic, type_quals);
-
- if (type_name_cstr) {
- bool type_handled = false;
- if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) {
- ObjCLanguage::MethodName objc_method(type_name_cstr, true);
- if (objc_method.IsValid(true)) {
- CompilerType class_opaque_type;
- ConstString class_name(objc_method.GetClassName());
- if (class_name) {
- TypeSP complete_objc_class_type_sp(
- dwarf->FindCompleteObjCDefinitionTypeForDIE(
- DWARFDIE(), class_name, false));
-
- if (complete_objc_class_type_sp) {
- CompilerType type_clang_forward_type =
- complete_objc_class_type_sp->GetForwardCompilerType();
- if (ClangASTContext::IsObjCObjectOrInterfaceType(
- type_clang_forward_type))
- class_opaque_type = type_clang_forward_type;
- }
- }
+ if (die.HasChildren()) {
+ bool skip_artificial = true;
+ ParseChildParameters(containing_decl_ctx, die, skip_artificial, is_static,
+ is_variadic, has_template_params,
+ function_param_types, function_param_decls,
+ type_quals);
+ }
- if (class_opaque_type) {
- // If accessibility isn't set to anything valid, assume public
- // for now...
- if (accessibility == eAccessNone)
- accessibility = eAccessPublic;
-
- clang::ObjCMethodDecl *objc_method_decl =
- m_ast.AddMethodToObjCObjectType(
- class_opaque_type, type_name_cstr, clang_type,
- accessibility, is_artificial, is_variadic);
- type_handled = objc_method_decl != NULL;
- if (type_handled) {
- LinkDeclContextToDIE(
- ClangASTContext::GetAsDeclContext(objc_method_decl), die);
- m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID());
- } else {
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), "
- "please file a bug and attach the file at the start of "
- "this error message",
- die.GetOffset(), tag, DW_TAG_value_to_name(tag));
+ bool ignore_containing_context = false;
+ // Check for templatized class member functions. If we had any
+ // DW_TAG_template_type_parameter or DW_TAG_template_value_parameter
+ // the DW_TAG_subprogram DIE, then we can't let this become a method in
+ // a class. Why? Because templatized functions are only emitted if one
+ // of the templatized methods is used in the current compile unit and
+ // we will end up with classes that may or may not include these member
+ // functions and this means one class won't match another class
+ // definition and it affects our ability to use a class in the clang
+ // expression parser. So for the greater good, we currently must not
+ // allow any template member functions in a class definition.
+ if (is_cxx_method && has_template_params) {
+ ignore_containing_context = true;
+ is_cxx_method = false;
+ }
+
+ // clang_type will get the function prototype clang type after this
+ // call
+ clang_type = m_ast.CreateFunctionType(
+ return_clang_type, function_param_types.data(),
+ function_param_types.size(), is_variadic, type_quals);
+
+ if (attrs.name) {
+ bool type_handled = false;
+ if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) {
+ ObjCLanguage::MethodName objc_method(attrs.name.GetStringRef(), true);
+ if (objc_method.IsValid(true)) {
+ CompilerType class_opaque_type;
+ ConstString class_name(objc_method.GetClassName());
+ if (class_name) {
+ TypeSP complete_objc_class_type_sp(
+ dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(),
+ class_name, false));
+
+ if (complete_objc_class_type_sp) {
+ CompilerType type_clang_forward_type =
+ complete_objc_class_type_sp->GetForwardCompilerType();
+ if (ClangASTContext::IsObjCObjectOrInterfaceType(
+ type_clang_forward_type))
+ class_opaque_type = type_clang_forward_type;
+ }
+ }
+
+ if (class_opaque_type) {
+ // If accessibility isn't set to anything valid, assume public
+ // for now...
+ if (attrs.accessibility == eAccessNone)
+ attrs.accessibility = eAccessPublic;
+
+ clang::ObjCMethodDecl *objc_method_decl =
+ m_ast.AddMethodToObjCObjectType(
+ class_opaque_type, attrs.name.GetCString(), clang_type,
+ attrs.accessibility, attrs.is_artificial, is_variadic);
+ type_handled = objc_method_decl != NULL;
+ if (type_handled) {
+ LinkDeclContextToDIE(
+ ClangASTContext::GetAsDeclContext(objc_method_decl), die);
+ m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID());
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), "
+ "please file a bug and attach the file at the start of "
+ "this error message",
+ die.GetOffset(), tag, DW_TAG_value_to_name(tag));
+ }
+ }
+ } else if (is_cxx_method) {
+ // Look at the parent of this DIE and see if is is a class or
+ // struct and see if this is actually a C++ method
+ Type *class_type = dwarf->ResolveType(decl_ctx_die);
+ if (class_type) {
+ bool alternate_defn = false;
+ if (class_type->GetID() != decl_ctx_die.GetID() ||
+ decl_ctx_die.GetContainingDWOModuleDIE()) {
+ alternate_defn = true;
+
+ // We uniqued the parent class of this function to another
+ // class so we now need to associate all dies under
+ // "decl_ctx_die" to DIEs in the DIE for "class_type"...
+ DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID());
+
+ if (class_type_die) {
+ std::vector<DWARFDIE> failures;
+
+ CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die,
+ class_type, failures);
+
+ // FIXME do something with these failures that's smarter
+ // than
+ // just dropping them on the ground. Unfortunately classes
+ // don't like having stuff added to them after their
+ // definitions are complete...
+
+ type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
+ if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
+ type_sp = type_ptr->shared_from_this();
+ break;
}
}
- } else if (is_cxx_method) {
- // Look at the parent of this DIE and see if is is a class or
- // struct and see if this is actually a C++ method
- Type *class_type = dwarf->ResolveType(decl_ctx_die);
- if (class_type) {
- bool alternate_defn = false;
- if (class_type->GetID() != decl_ctx_die.GetID() ||
- decl_ctx_die.GetContainingDWOModuleDIE()) {
- alternate_defn = true;
-
- // We uniqued the parent class of this function to another
- // class so we now need to associate all dies under
- // "decl_ctx_die" to DIEs in the DIE for "class_type"...
- SymbolFileDWARF *class_symfile = NULL;
- DWARFDIE class_type_die;
-
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(
- SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(
- class_type->GetID()));
- class_type_die = class_symfile->DebugInfo()->GetDIE(
- DIERef(class_type->GetID(), dwarf));
- } else {
- class_symfile = dwarf;
- class_type_die = dwarf->DebugInfo()->GetDIE(
- DIERef(class_type->GetID(), dwarf));
- }
- if (class_type_die) {
- DWARFDIECollection failures;
-
- CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die,
- class_type, failures);
-
- // FIXME do something with these failures that's smarter
- // than
- // just dropping them on the ground. Unfortunately classes
- // don't like having stuff added to them after their
- // definitions are complete...
-
- type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
- if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
- type_sp = type_ptr->shared_from_this();
- break;
- }
- }
- }
+ }
- if (specification_die_form.IsValid()) {
- // We have a specification which we are going to base our
- // function prototype off of, so we need this type to be
- // completed so that the m_die_to_decl_ctx for the method in
- // the specification has a valid clang decl context.
- class_type->GetForwardCompilerType();
- // If we have a specification, then the function type should
- // have been made with the specification and not with this
- // die.
- DWARFDIE spec_die = dwarf->DebugInfo()->GetDIE(
- DIERef(specification_die_form));
- clang::DeclContext *spec_clang_decl_ctx =
- GetClangDeclContextForDIE(spec_die);
- if (spec_clang_decl_ctx) {
- LinkDeclContextToDIE(spec_clang_decl_ctx, die);
- } else {
- dwarf->GetObjectFile()->GetModule()->ReportWarning(
- "0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8" PRIx64
- ") has no decl\n",
- die.GetID(), specification_die_form.Reference());
- }
- type_handled = true;
- } else if (abstract_origin_die_form.IsValid()) {
- // We have a specification which we are going to base our
- // function prototype off of, so we need this type to be
- // completed so that the m_die_to_decl_ctx for the method in
- // the abstract origin has a valid clang decl context.
+ if (attrs.specification.IsValid()) {
+ // We have a specification which we are going to base our
+ // function prototype off of, so we need this type to be
+ // completed so that the m_die_to_decl_ctx for the method in
+ // the specification has a valid clang decl context.
+ class_type->GetForwardCompilerType();
+ // If we have a specification, then the function type should
+ // have been made with the specification and not with this
+ // die.
+ DWARFDIE spec_die = attrs.specification.Reference();
+ clang::DeclContext *spec_clang_decl_ctx =
+ GetClangDeclContextForDIE(spec_die);
+ if (spec_clang_decl_ctx) {
+ LinkDeclContextToDIE(spec_clang_decl_ctx, die);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8x"
+ ") has no decl\n",
+ die.GetID(), spec_die.GetOffset());
+ }
+ type_handled = true;
+ } else if (attrs.abstract_origin.IsValid()) {
+ // We have a specification which we are going to base our
+ // function prototype off of, so we need this type to be
+ // completed so that the m_die_to_decl_ctx for the method in
+ // the abstract origin has a valid clang decl context.
+ class_type->GetForwardCompilerType();
+
+ DWARFDIE abs_die = attrs.abstract_origin.Reference();
+ clang::DeclContext *abs_clang_decl_ctx =
+ GetClangDeclContextForDIE(abs_die);
+ if (abs_clang_decl_ctx) {
+ LinkDeclContextToDIE(abs_clang_decl_ctx, die);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8x"
+ ") has no decl\n",
+ die.GetID(), abs_die.GetOffset());
+ }
+ type_handled = true;
+ } else {
+ CompilerType class_opaque_type =
class_type->GetForwardCompilerType();
-
- DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE(
- DIERef(abstract_origin_die_form));
- clang::DeclContext *abs_clang_decl_ctx =
- GetClangDeclContextForDIE(abs_die);
- if (abs_clang_decl_ctx) {
- LinkDeclContextToDIE(abs_clang_decl_ctx, die);
+ if (ClangASTContext::IsCXXClassType(class_opaque_type)) {
+ if (class_opaque_type.IsBeingDefined() || alternate_defn) {
+ if (!is_static && !die.HasChildren()) {
+ // We have a C++ member function with no children (this
+ // pointer!) and clang will get mad if we try and make
+ // a function that isn't well formed in the DWARF, so
+ // we will just skip it...
+ type_handled = true;
} else {
- dwarf->GetObjectFile()->GetModule()->ReportWarning(
- "0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8" PRIx64
- ") has no decl\n",
- die.GetID(), abstract_origin_die_form.Reference());
- }
- type_handled = true;
- } else {
- CompilerType class_opaque_type =
- class_type->GetForwardCompilerType();
- if (ClangASTContext::IsCXXClassType(class_opaque_type)) {
- if (class_opaque_type.IsBeingDefined() || alternate_defn) {
- if (!is_static && !die.HasChildren()) {
- // We have a C++ member function with no children (this
- // pointer!) and clang will get mad if we try and make
- // a function that isn't well formed in the DWARF, so
- // we will just skip it...
- type_handled = true;
- } else {
- bool add_method = true;
- if (alternate_defn) {
- // If an alternate definition for the class exists,
- // then add the method only if an equivalent is not
- // already present.
- clang::CXXRecordDecl *record_decl =
- m_ast.GetAsCXXRecordDecl(
- class_opaque_type.GetOpaqueQualType());
- if (record_decl) {
- for (auto method_iter = record_decl->method_begin();
- method_iter != record_decl->method_end();
- method_iter++) {
- clang::CXXMethodDecl *method_decl = *method_iter;
- if (method_decl->getNameInfo().getAsString() ==
- std::string(type_name_cstr)) {
- if (method_decl->getType() ==
- ClangUtil::GetQualType(clang_type)) {
- add_method = false;
- LinkDeclContextToDIE(
- ClangASTContext::GetAsDeclContext(
- method_decl),
- die);
- type_handled = true;
-
- break;
- }
- }
+ bool add_method = true;
+ if (alternate_defn) {
+ // If an alternate definition for the class exists,
+ // then add the method only if an equivalent is not
+ // already present.
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(
+ class_opaque_type.GetOpaqueQualType());
+ if (record_decl) {
+ for (auto method_iter = record_decl->method_begin();
+ method_iter != record_decl->method_end();
+ method_iter++) {
+ clang::CXXMethodDecl *method_decl = *method_iter;
+ if (method_decl->getNameInfo().getAsString() ==
+ attrs.name.GetStringRef()) {
+ if (method_decl->getType() ==
+ ClangUtil::GetQualType(clang_type)) {
+ add_method = false;
+ LinkDeclContextToDIE(
+ ClangASTContext::GetAsDeclContext(
+ method_decl),
+ die);
+ type_handled = true;
+
+ break;
}
}
}
+ }
+ }
- if (add_method) {
- llvm::PrettyStackTraceFormat stack_trace(
- "SymbolFileDWARF::ParseType() is adding a method "
- "%s to class %s in DIE 0x%8.8" PRIx64 " from %s",
- type_name_cstr,
- class_type->GetName().GetCString(), die.GetID(),
- dwarf->GetObjectFile()
- ->GetFileSpec()
- .GetPath()
- .c_str());
-
- const bool is_attr_used = false;
- // Neither GCC 4.2 nor clang++ currently set a valid
- // accessibility in the DWARF for C++ methods...
- // Default to public for now...
- if (accessibility == eAccessNone)
- accessibility = eAccessPublic;
-
- clang::CXXMethodDecl *cxx_method_decl =
- m_ast.AddMethodToCXXRecordType(
- class_opaque_type.GetOpaqueQualType(),
- type_name_cstr, mangled_name_cstr, clang_type,
- accessibility, is_virtual, is_static,
- is_inline, is_explicit, is_attr_used,
- is_artificial);
-
- type_handled = cxx_method_decl != NULL;
-
- if (type_handled) {
- LinkDeclContextToDIE(
- ClangASTContext::GetAsDeclContext(
- cxx_method_decl),
- die);
-
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
-
- if (!object_pointer_name.empty()) {
- metadata.SetObjectPtrName(
- object_pointer_name.c_str());
- if (log)
- log->Printf(
- "Setting object pointer name: %s on method "
- "object %p.\n",
- object_pointer_name.c_str(),
- static_cast<void *>(cxx_method_decl));
- }
- m_ast.SetMetadata(cxx_method_decl, metadata);
- } else {
- ignore_containing_context = true;
- }
+ if (add_method) {
+ llvm::PrettyStackTraceFormat stack_trace(
+ "SymbolFileDWARF::ParseType() is adding a method "
+ "%s to class %s in DIE 0x%8.8" PRIx64 " from %s",
+ attrs.name.GetCString(),
+ class_type->GetName().GetCString(), die.GetID(),
+ dwarf->GetObjectFile()
+ ->GetFileSpec()
+ .GetPath()
+ .c_str());
+
+ const bool is_attr_used = false;
+ // Neither GCC 4.2 nor clang++ currently set a valid
+ // accessibility in the DWARF for C++ methods...
+ // Default to public for now...
+ if (attrs.accessibility == eAccessNone)
+ attrs.accessibility = eAccessPublic;
+
+ clang::CXXMethodDecl *cxx_method_decl =
+ m_ast.AddMethodToCXXRecordType(
+ class_opaque_type.GetOpaqueQualType(),
+ attrs.name.GetCString(), attrs.mangled_name,
+ clang_type, attrs.accessibility, attrs.is_virtual,
+ is_static, attrs.is_inline, attrs.is_explicit,
+ is_attr_used, attrs.is_artificial);
+
+ type_handled = cxx_method_decl != NULL;
+
+ if (type_handled) {
+ LinkDeclContextToDIE(
+ ClangASTContext::GetAsDeclContext(cxx_method_decl),
+ die);
+
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+
+ if (!object_pointer_name.empty()) {
+ metadata.SetObjectPtrName(
+ object_pointer_name.c_str());
+ if (log)
+ log->Printf(
+ "Setting object pointer name: %s on method "
+ "object %p.\n",
+ object_pointer_name.c_str(),
+ static_cast<void *>(cxx_method_decl));
}
+ m_ast.SetMetadata(cxx_method_decl, metadata);
+ } else {
+ ignore_containing_context = true;
}
- } else {
- // We were asked to parse the type for a method in a
- // class, yet the class hasn't been asked to complete
- // itself through the clang::ExternalASTSource protocol,
- // so we need to just have the class complete itself and
- // do things the right way, then our
- // DIE should then have an entry in the
- // dwarf->GetDIEToType() map. First
- // we need to modify the dwarf->GetDIEToType() so it
- // doesn't think we are trying to parse this DIE
- // anymore...
- dwarf->GetDIEToType()[die.GetDIE()] = NULL;
-
- // Now we get the full type to force our class type to
- // complete itself using the clang::ExternalASTSource
- // protocol which will parse all base classes and all
- // methods (including the method for this DIE).
- class_type->GetFullCompilerType();
-
- // The type for this DIE should have been filled in the
- // function call above
- type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
- if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
- type_sp = type_ptr->shared_from_this();
- break;
- }
-
- // FIXME This is fixing some even uglier behavior but we
- // really need to
- // uniq the methods of each class as well as the class
- // itself. <rdar://problem/11240464>
- type_handled = true;
}
}
- }
- }
- }
- }
-
- if (!type_handled) {
- clang::FunctionDecl *function_decl = nullptr;
-
- if (abstract_origin_die_form.IsValid()) {
- DWARFDIE abs_die =
- dwarf->DebugInfo()->GetDIE(DIERef(abstract_origin_die_form));
-
- SymbolContext sc;
-
- if (dwarf->ResolveType(abs_die)) {
- function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(
- GetCachedClangDeclContextForDIE(abs_die));
+ } else {
+ // We were asked to parse the type for a method in a
+ // class, yet the class hasn't been asked to complete
+ // itself through the clang::ExternalASTSource protocol,
+ // so we need to just have the class complete itself and
+ // do things the right way, then our
+ // DIE should then have an entry in the
+ // dwarf->GetDIEToType() map. First
+ // we need to modify the dwarf->GetDIEToType() so it
+ // doesn't think we are trying to parse this DIE
+ // anymore...
+ dwarf->GetDIEToType()[die.GetDIE()] = NULL;
+
+ // Now we get the full type to force our class type to
+ // complete itself using the clang::ExternalASTSource
+ // protocol which will parse all base classes and all
+ // methods (including the method for this DIE).
+ class_type->GetFullCompilerType();
+
+ // The type for this DIE should have been filled in the
+ // function call above
+ type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
+ if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
+ type_sp = type_ptr->shared_from_this();
+ break;
+ }
- if (function_decl) {
- LinkDeclContextToDIE(function_decl, die);
+ // FIXME This is fixing some even uglier behavior but we
+ // really need to
+ // uniq the methods of each class as well as the class
+ // itself. <rdar://problem/11240464>
+ type_handled = true;
}
}
}
+ }
+ }
+ }
- if (!function_decl) {
- // We just have a function that isn't part of a class
- function_decl = m_ast.CreateFunctionDeclaration(
- ignore_containing_context ? m_ast.GetTranslationUnitDecl()
- : containing_decl_ctx,
- type_name_cstr, clang_type, storage, is_inline);
-
- if (has_template_params) {
- ClangASTContext::TemplateParameterInfos template_param_infos;
- ParseTemplateParameterInfos(die, template_param_infos);
- clang::FunctionTemplateDecl *func_template_decl =
- m_ast.CreateFunctionTemplateDecl(
- containing_decl_ctx, function_decl, type_name_cstr,
- template_param_infos);
- m_ast.CreateFunctionTemplateSpecializationInfo(
- function_decl, func_template_decl, template_param_infos);
- }
-
- lldbassert(function_decl);
-
- if (function_decl) {
- LinkDeclContextToDIE(function_decl, die);
+ if (!type_handled) {
+ clang::FunctionDecl *function_decl = nullptr;
+ clang::FunctionDecl *template_function_decl = nullptr;
- if (!function_param_decls.empty())
- m_ast.SetFunctionParameters(function_decl,
- &function_param_decls.front(),
- function_param_decls.size());
+ if (attrs.abstract_origin.IsValid()) {
+ DWARFDIE abs_die = attrs.abstract_origin.Reference();
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
+ if (dwarf->ResolveType(abs_die)) {
+ function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(
+ GetCachedClangDeclContextForDIE(abs_die));
- if (!object_pointer_name.empty()) {
- metadata.SetObjectPtrName(object_pointer_name.c_str());
- if (log)
- log->Printf("Setting object pointer name: %s on function "
- "object %p.",
- object_pointer_name.c_str(),
- static_cast<void *>(function_decl));
- }
- m_ast.SetMetadata(function_decl, metadata);
- }
+ if (function_decl) {
+ LinkDeclContextToDIE(function_decl, die);
}
}
}
- type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL,
- LLDB_INVALID_UID, Type::eEncodingIsUID, &decl,
- clang_type, Type::eResolveStateFull));
- assert(type_sp.get());
- } break;
-
- case DW_TAG_array_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- DWARFFormValue type_die_form;
- int64_t first_index = 0;
- uint32_t byte_stride = 0;
- uint32_t bit_stride = 0;
- bool is_vector = false;
- const size_t num_attributes = die.GetAttributes(attributes);
-
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
- break;
- case DW_AT_decl_line:
- decl.SetLine(form_value.Unsigned());
- break;
- case DW_AT_decl_column:
- decl.SetColumn(form_value.Unsigned());
- break;
- case DW_AT_name:
- type_name_cstr = form_value.AsCString();
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_type:
- type_die_form = form_value;
- break;
- case DW_AT_byte_size:
- break; // byte_size = form_value.Unsigned(); break;
- case DW_AT_byte_stride:
- byte_stride = form_value.Unsigned();
- break;
- case DW_AT_bit_stride:
- bit_stride = form_value.Unsigned();
- break;
- case DW_AT_GNU_vector:
- is_vector = form_value.Boolean();
- break;
- case DW_AT_accessibility:
- break; // accessibility =
- // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration:
- break; // is_forward_declaration = form_value.Boolean(); break;
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_data_location:
- case DW_AT_description:
- case DW_AT_ordering:
- case DW_AT_start_scope:
- case DW_AT_visibility:
- case DW_AT_specification:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
- }
- }
- }
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
+ if (!function_decl) {
+ // We just have a function that isn't part of a class
+ function_decl = m_ast.CreateFunctionDeclaration(
+ ignore_containing_context ? m_ast.GetTranslationUnitDecl()
+ : containing_decl_ctx,
+ attrs.name.GetCString(), clang_type, attrs.storage,
+ attrs.is_inline);
- DIERef type_die_ref(type_die_form);
- Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
+ if (has_template_params) {
+ ClangASTContext::TemplateParameterInfos template_param_infos;
+ ParseTemplateParameterInfos(die, template_param_infos);
+ template_function_decl = m_ast.CreateFunctionDeclaration(
+ ignore_containing_context ? m_ast.GetTranslationUnitDecl()
+ : containing_decl_ctx,
+ attrs.name.GetCString(), clang_type, attrs.storage,
+ attrs.is_inline);
+ clang::FunctionTemplateDecl *func_template_decl =
+ m_ast.CreateFunctionTemplateDecl(
+ containing_decl_ctx, template_function_decl,
+ attrs.name.GetCString(), template_param_infos);
+ m_ast.CreateFunctionTemplateSpecializationInfo(
+ function_decl, func_template_decl, template_param_infos);
+ }
- if (element_type) {
- auto array_info = ParseChildArrayInfo(die);
- if (array_info) {
- first_index = array_info->first_index;
- byte_stride = array_info->byte_stride;
- bit_stride = array_info->bit_stride;
- }
- if (byte_stride == 0 && bit_stride == 0)
- byte_stride = element_type->GetByteSize();
- CompilerType array_element_type =
- element_type->GetForwardCompilerType();
-
- if (ClangASTContext::IsCXXClassType(array_element_type) &&
- !array_element_type.GetCompleteType()) {
- ModuleSP module_sp = die.GetModule();
- if (module_sp) {
- if (die.GetCU()->GetProducer() == eProducerClang)
- module_sp->ReportError(
- "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
- "class/union/struct element type DIE 0x%8.8x that is a "
- "forward declaration, not a complete definition.\nTry "
- "compiling the source file with -fstandalone-debug or "
- "disable -gmodules",
- die.GetOffset(), type_die_ref.die_offset);
- else
- module_sp->ReportError(
- "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
- "class/union/struct element type DIE 0x%8.8x that is a "
- "forward declaration, not a complete definition.\nPlease "
- "file a bug against the compiler and include the "
- "preprocessed output for %s",
- die.GetOffset(), type_die_ref.die_offset,
- die.GetLLDBCompileUnit()
- ? die.GetLLDBCompileUnit()->GetPath().c_str()
- : "the source file");
- }
+ lldbassert(function_decl);
- // We have no choice other than to pretend that the element class
- // type is complete. If we don't do this, clang will crash when
- // trying to layout the class. Since we provide layout
- // assistance, all ivars in this class and other classes will be
- // fine, this is the best we can do short of crashing.
- if (ClangASTContext::StartTagDeclarationDefinition(
- array_element_type)) {
- ClangASTContext::CompleteTagDeclarationDefinition(
- array_element_type);
- } else {
- module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to "
- "start its definition.\nPlease file a "
- "bug and attach the file at the start "
- "of this error message",
- type_die_ref.die_offset);
- }
- }
+ if (function_decl) {
+ LinkDeclContextToDIE(function_decl, die);
- uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
- if (array_info && array_info->element_orders.size() > 0) {
- uint64_t num_elements = 0;
- auto end = array_info->element_orders.rend();
- for (auto pos = array_info->element_orders.rbegin(); pos != end;
- ++pos) {
- num_elements = *pos;
- clang_type = m_ast.CreateArrayType(array_element_type,
- num_elements, is_vector);
- array_element_type = clang_type;
- array_element_bit_stride =
- num_elements ? array_element_bit_stride * num_elements
- : array_element_bit_stride;
- }
- } else {
- clang_type =
- m_ast.CreateArrayType(array_element_type, 0, is_vector);
+ if (!function_param_decls.empty()) {
+ m_ast.SetFunctionParameters(function_decl,
+ &function_param_decls.front(),
+ function_param_decls.size());
+ if (template_function_decl)
+ m_ast.SetFunctionParameters(template_function_decl,
+ &function_param_decls.front(),
+ function_param_decls.size());
}
- ConstString empty_name;
- type_sp.reset(new Type(
- die.GetID(), dwarf, empty_name, array_element_bit_stride / 8,
- NULL, DIERef(type_die_form).GetUID(dwarf), Type::eEncodingIsUID,
- &decl, clang_type, Type::eResolveStateFull));
- type_sp->SetEncodingType(element_type);
- m_ast.SetMetadataAsUserID(clang_type.GetOpaqueQualType(),
- die.GetID());
- }
- }
- } break;
-
- case DW_TAG_ptr_to_member_type: {
- DWARFFormValue type_die_form;
- DWARFFormValue containing_type_die_form;
-
- const size_t num_attributes = die.GetAttributes(attributes);
-
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_type:
- type_die_form = form_value;
- break;
- case DW_AT_containing_type:
- containing_type_die_form = form_value;
- break;
- }
- }
- }
-
- Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
- Type *class_type =
- dwarf->ResolveTypeUID(DIERef(containing_type_die_form));
-
- CompilerType pointee_clang_type =
- pointee_type->GetForwardCompilerType();
- CompilerType class_clang_type = class_type->GetLayoutCompilerType();
- clang_type = ClangASTContext::CreateMemberPointerType(
- class_clang_type, pointee_clang_type);
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
- if (llvm::Optional<uint64_t> clang_type_size =
- clang_type.GetByteSize(nullptr)) {
- byte_size = *clang_type_size;
- type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
- byte_size, NULL, LLDB_INVALID_UID,
- Type::eEncodingIsUID, NULL, clang_type,
- Type::eResolveStateForward));
+ if (!object_pointer_name.empty()) {
+ metadata.SetObjectPtrName(object_pointer_name.c_str());
+ if (log)
+ log->Printf("Setting object pointer name: %s on function "
+ "object %p.",
+ object_pointer_name.c_str(),
+ static_cast<void *>(function_decl));
+ }
+ m_ast.SetMetadata(function_decl, metadata);
}
}
-
- break;
}
- default:
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "{0x%8.8x}: unhandled type tag 0x%4.4x (%s), please file a bug and "
- "attach the file at the start of this error message",
- die.GetOffset(), tag, DW_TAG_value_to_name(tag));
- break;
+ }
+ type_sp = std::make_shared<Type>(
+ die.GetID(), dwarf, attrs.name, llvm::None, nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, &attrs.decl, clang_type, Type::eResolveStateFull);
+ assert(type_sp.get());
+ } break;
+
+ case DW_TAG_array_type: {
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+
+ DWARFDIE type_die = attrs.type.Reference();
+ Type *element_type = dwarf->ResolveTypeUID(type_die, true);
+
+ if (element_type) {
+ auto array_info = ParseChildArrayInfo(die);
+ if (array_info) {
+ attrs.byte_stride = array_info->byte_stride;
+ attrs.bit_stride = array_info->bit_stride;
}
+ if (attrs.byte_stride == 0 && attrs.bit_stride == 0)
+ attrs.byte_stride = element_type->GetByteSize().getValueOr(0);
+ CompilerType array_element_type = element_type->GetForwardCompilerType();
+
+ if (ClangASTContext::IsCXXClassType(array_element_type) &&
+ !array_element_type.GetCompleteType()) {
+ ModuleSP module_sp = die.GetModule();
+ if (module_sp) {
+ if (die.GetCU()->GetProducer() == eProducerClang)
+ module_sp->ReportError(
+ "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
+ "class/union/struct element type DIE 0x%8.8x that is a "
+ "forward declaration, not a complete definition.\nTry "
+ "compiling the source file with -fstandalone-debug or "
+ "disable -gmodules",
+ die.GetOffset(), type_die.GetOffset());
+ else
+ module_sp->ReportError(
+ "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
+ "class/union/struct element type DIE 0x%8.8x that is a "
+ "forward declaration, not a complete definition.\nPlease "
+ "file a bug against the compiler and include the "
+ "preprocessed output for %s",
+ die.GetOffset(), type_die.GetOffset(),
+ GetUnitName(die).c_str());
+ }
- if (type_sp.get()) {
- DWARFDIE sc_parent_die =
- SymbolFileDWARF::GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die.Tag();
-
- SymbolContextScope *symbol_context_scope = NULL;
- if (sc_parent_tag == DW_TAG_compile_unit ||
- sc_parent_tag == DW_TAG_partial_unit) {
- symbol_context_scope = sc.comp_unit;
- } else if (sc.function != NULL && sc_parent_die) {
- symbol_context_scope =
- sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
- if (symbol_context_scope == NULL)
- symbol_context_scope = sc.function;
+ // We have no choice other than to pretend that the element class
+ // type is complete. If we don't do this, clang will crash when
+ // trying to layout the class. Since we provide layout
+ // assistance, all ivars in this class and other classes will be
+ // fine, this is the best we can do short of crashing.
+ if (ClangASTContext::StartTagDeclarationDefinition(
+ array_element_type)) {
+ ClangASTContext::CompleteTagDeclarationDefinition(array_element_type);
+ } else {
+ module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to "
+ "start its definition.\nPlease file a "
+ "bug and attach the file at the start "
+ "of this error message",
+ type_die.GetOffset());
}
+ }
- if (symbol_context_scope != NULL) {
- type_sp->SetSymbolContextScope(symbol_context_scope);
+ uint64_t array_element_bit_stride =
+ attrs.byte_stride * 8 + attrs.bit_stride;
+ if (array_info && array_info->element_orders.size() > 0) {
+ uint64_t num_elements = 0;
+ auto end = array_info->element_orders.rend();
+ for (auto pos = array_info->element_orders.rbegin(); pos != end;
+ ++pos) {
+ num_elements = *pos;
+ clang_type = m_ast.CreateArrayType(array_element_type, num_elements,
+ attrs.is_vector);
+ array_element_type = clang_type;
+ array_element_bit_stride =
+ num_elements ? array_element_bit_stride * num_elements
+ : array_element_bit_stride;
}
+ } else {
+ clang_type = m_ast.CreateArrayType(array_element_type, 0, attrs.is_vector);
+ }
+ ConstString empty_name;
+ type_sp = std::make_shared<Type>(
+ die.GetID(), dwarf, empty_name, array_element_bit_stride / 8, nullptr,
+ dwarf->GetUID(type_die), Type::eEncodingIsUID, &attrs.decl,
+ clang_type, Type::eResolveStateFull);
+ type_sp->SetEncodingType(element_type);
+ m_ast.SetMetadataAsUserID(clang_type.GetOpaqueQualType(), die.GetID());
+ }
+ } break;
- // We are ready to put this type into the uniqued list up at the module
- // level
- type_list->Insert(type_sp);
+ case DW_TAG_ptr_to_member_type: {
+ Type *pointee_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true);
+ Type *class_type =
+ dwarf->ResolveTypeUID(attrs.containing_type.Reference(), true);
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- }
- } else if (type_ptr != DIE_IS_BEING_PARSED) {
- type_sp = type_ptr->shared_from_this();
+ CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType();
+ CompilerType class_clang_type = class_type->GetLayoutCompilerType();
+
+ clang_type = ClangASTContext::CreateMemberPointerType(class_clang_type,
+ pointee_clang_type);
+
+ if (llvm::Optional<uint64_t> clang_type_size =
+ clang_type.GetByteSize(nullptr)) {
+ type_sp = std::make_shared<Type>(
+ die.GetID(), dwarf, attrs.name, *clang_type_size, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, nullptr, clang_type,
+ Type::eResolveStateForward);
+ }
+
+ break;
+ }
+ default:
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "{0x%8.8x}: unhandled type tag 0x%4.4x (%s), please file a bug and "
+ "attach the file at the start of this error message",
+ die.GetOffset(), tag, DW_TAG_value_to_name(tag));
+ break;
+ }
+
+ if (type_sp.get()) {
+ DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
+ dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+
+ SymbolContextScope *symbol_context_scope = NULL;
+ if (sc_parent_tag == DW_TAG_compile_unit ||
+ sc_parent_tag == DW_TAG_partial_unit) {
+ symbol_context_scope = sc.comp_unit;
+ } else if (sc.function != NULL && sc_parent_die) {
+ symbol_context_scope =
+ sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
+ if (symbol_context_scope == NULL)
+ symbol_context_scope = sc.function;
+ } else
+ symbol_context_scope = sc.module_sp.get();
+
+ if (symbol_context_scope != NULL) {
+ type_sp->SetSymbolContextScope(symbol_context_scope);
}
+
+ // We are ready to put this type into the uniqued list up at the module
+ // level
+ type_list->Insert(type_sp);
+
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
}
return type_sp;
}
@@ -1920,9 +1697,9 @@ public:
m_property_setter_name(property_setter_name),
m_property_getter_name(property_getter_name),
m_property_attributes(property_attributes) {
- if (metadata != NULL) {
- m_metadata_ap.reset(new ClangASTMetadata());
- *m_metadata_ap = *metadata;
+ if (metadata != nullptr) {
+ m_metadata_up.reset(new ClangASTMetadata());
+ *m_metadata_up = *metadata;
}
}
@@ -1940,9 +1717,9 @@ public:
m_property_getter_name = rhs.m_property_getter_name;
m_property_attributes = rhs.m_property_attributes;
- if (rhs.m_metadata_ap.get()) {
- m_metadata_ap.reset(new ClangASTMetadata());
- *m_metadata_ap = *rhs.m_metadata_ap;
+ if (rhs.m_metadata_up) {
+ m_metadata_up.reset(new ClangASTMetadata());
+ *m_metadata_up = *rhs.m_metadata_up;
}
return *this;
}
@@ -1951,7 +1728,7 @@ public:
return ClangASTContext::AddObjCClassProperty(
m_class_opaque_type, m_property_name, m_property_opaque_type,
m_ivar_decl, m_property_setter_name, m_property_getter_name,
- m_property_attributes, m_metadata_ap.get());
+ m_property_attributes, m_metadata_up.get());
}
private:
@@ -1962,7 +1739,7 @@ private:
const char *m_property_setter_name;
const char *m_property_getter_name;
uint32_t m_property_attributes;
- std::unique_ptr<ClangASTMetadata> m_metadata_ap;
+ std::unique_ptr<ClangASTMetadata> m_metadata_up;
};
bool DWARFASTParserClang::ParseTemplateDIE(
@@ -2015,7 +1792,7 @@ bool DWARFASTParserClang::ParseTemplateDIE(
case DW_AT_type:
if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- Type *lldb_type = die.ResolveTypeUID(DIERef(form_value));
+ Type *lldb_type = die.ResolveTypeUID(form_value.Reference());
if (lldb_type)
clang_type = lldb_type->GetForwardCompilerType();
}
@@ -2118,7 +1895,6 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
return false;
#if defined LLDB_CONFIGURATION_DEBUG
- //----------------------------------------------------------------------
// For debugging purposes, the LLDB_DWARF_DONT_COMPLETE_TYPENAMES environment
// variable can be set with one or more typenames separated by ';'
// characters. This will cause this function to not complete any types whose
@@ -2128,7 +1904,6 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
//
// LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo
// LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo;Bar;Baz
- //----------------------------------------------------------------------
const char *dont_complete_typenames_cstr =
getenv("LLDB_DWARF_DONT_COMPLETE_TYPENAMES");
if (dont_complete_typenames_cstr && dont_complete_typenames_cstr[0]) {
@@ -2191,26 +1966,21 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
default_accessibility = eAccessPrivate;
}
- SymbolContext sc(die.GetLLDBCompileUnit());
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
std::vector<int> member_accessibilities;
bool is_a_class = false;
// Parse members and base classes first
- DWARFDIECollection member_function_dies;
+ std::vector<DWARFDIE> member_function_dies;
DelayedPropertyList delayed_properties;
- ParseChildMembers(sc, die, clang_type, class_language, bases,
+ ParseChildMembers(die, clang_type, class_language, bases,
member_accessibilities, member_function_dies,
delayed_properties, default_accessibility, is_a_class,
layout_info);
// Now parse any methods if there were any...
- size_t num_functions = member_function_dies.Size();
- if (num_functions > 0) {
- for (size_t i = 0; i < num_functions; ++i) {
- dwarf->ResolveType(member_function_dies.GetDIEAtIndex(i));
- }
- }
+ for (const DWARFDIE &die : member_function_dies)
+ dwarf->ResolveType(die);
if (class_language == eLanguageTypeObjC) {
ConstString class_name(clang_type.GetTypeName());
@@ -2313,7 +2083,7 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
!layout_info.base_offsets.empty() ||
!layout_info.vbase_offsets.empty()) {
if (type)
- layout_info.bit_size = type->GetByteSize() * 8;
+ layout_info.bit_size = type->GetByteSize().getValueOr(0) * 8;
if (layout_info.bit_size == 0)
layout_info.bit_size =
die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
@@ -2394,11 +2164,10 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
case DW_TAG_enumeration_type:
if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
if (die.HasChildren()) {
- SymbolContext sc(die.GetLLDBCompileUnit());
bool is_signed = false;
clang_type.IsIntegerType(is_signed);
- ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(),
- die);
+ ParseChildEnumerators(clang_type, is_signed,
+ type->GetByteSize().getValueOr(0), die);
}
ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
}
@@ -2447,8 +2216,8 @@ DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
}
size_t DWARFASTParserClang::ParseChildEnumerators(
- const SymbolContext &sc, lldb_private::CompilerType &clang_type,
- bool is_signed, uint32_t enumerator_byte_size, const DWARFDIE &parent_die) {
+ lldb_private::CompilerType &clang_type, bool is_signed,
+ uint32_t enumerator_byte_size, const DWARFDIE &parent_die) {
if (!parent_die)
return 0;
@@ -2461,7 +2230,7 @@ size_t DWARFASTParserClang::ParseChildEnumerators(
DWARFAttributes attributes;
const size_t num_child_attributes = die.GetAttributes(attributes);
if (num_child_attributes > 0) {
- const char *name = NULL;
+ const char *name = nullptr;
bool got_value = false;
int64_t enum_value = 0;
Declaration decl;
@@ -2487,8 +2256,7 @@ size_t DWARFASTParserClang::ParseChildEnumerators(
case DW_AT_description:
default:
case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
+ decl.SetFile(die.GetCU()->GetFile(form_value.Unsigned()));
break;
case DW_AT_decl_line:
decl.SetLine(form_value.Unsigned());
@@ -2564,20 +2332,20 @@ protected:
Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
const DWARFDIE &die) {
DWARFRangeList func_ranges;
- const char *name = NULL;
- const char *mangled = NULL;
+ const char *name = nullptr;
+ const char *mangled = nullptr;
int decl_file = 0;
int decl_line = 0;
int decl_column = 0;
int call_file = 0;
int call_line = 0;
int call_column = 0;
- DWARFExpression frame_base(die.GetCU());
+ DWARFExpression frame_base;
const dw_tag_t tag = die.Tag();
if (tag != DW_TAG_subprogram)
- return NULL;
+ return nullptr;
if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
decl_column, call_file, call_line, call_column,
@@ -2603,7 +2371,8 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
func_name.SetValue(ConstString(mangled), true);
else if ((die.GetParent().Tag() == DW_TAG_compile_unit ||
die.GetParent().Tag() == DW_TAG_partial_unit) &&
- Language::LanguageIsCPlusPlus(die.GetLanguage()) && name &&
+ Language::LanguageIsCPlusPlus(die.GetLanguage()) &&
+ !Language::LanguageIsObjC(die.GetLanguage()) && name &&
strcmp(name, "main") != 0) {
// If the mangled name is not present in the DWARF, generate the
// demangled name using the decl context. We skip if the function is
@@ -2622,9 +2391,9 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
clang::DeclContext *containing_decl_ctx =
GetClangDeclContextContainingDIE(die, nullptr);
- ParseChildParameters(comp_unit, containing_decl_ctx, die, true,
- is_static, is_variadic, has_template_params,
- param_types, param_decls, type_quals);
+ ParseChildParameters(containing_decl_ctx, die, true, is_static,
+ is_variadic, has_template_params, param_types,
+ param_decls, type_quals);
sstr << "(";
for (size_t i = 0; i < param_types.size(); i++) {
if (i > 0)
@@ -2642,26 +2411,26 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
func_name.SetValue(ConstString(name), false);
FunctionSP func_sp;
- std::unique_ptr<Declaration> decl_ap;
+ std::unique_ptr<Declaration> decl_up;
if (decl_file != 0 || decl_line != 0 || decl_column != 0)
- decl_ap.reset(new Declaration(
- comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file),
- decl_line, decl_column));
+ decl_up.reset(new Declaration(die.GetCU()->GetFile(decl_file),
+ decl_line, decl_column));
SymbolFileDWARF *dwarf = die.GetDWARF();
// Supply the type _only_ if it has already been parsed
Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE());
- assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
+ assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED);
if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
const user_id_t func_user_id = die.GetID();
- func_sp.reset(new Function(&comp_unit,
+ func_sp =
+ std::make_shared<Function>(&comp_unit,
func_user_id, // UserID is the DIE offset
func_user_id, func_name, func_type,
- func_range)); // first address range
+ func_range); // first address range
- if (func_sp.get() != NULL) {
+ if (func_sp.get() != nullptr) {
if (frame_base.IsValid())
func_sp->GetFrameBaseExpression() = frame_base;
comp_unit.AddFunction(func_sp);
@@ -2670,19 +2439,19 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
}
}
}
- return NULL;
+ return nullptr;
}
bool DWARFASTParserClang::ParseChildMembers(
- const SymbolContext &sc, const DWARFDIE &parent_die,
- CompilerType &class_clang_type, const LanguageType class_language,
+ const DWARFDIE &parent_die, CompilerType &class_clang_type,
+ const LanguageType class_language,
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
std::vector<int> &member_accessibilities,
- DWARFDIECollection &member_function_dies,
+ std::vector<DWARFDIE> &member_function_dies,
DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info) {
if (!parent_die)
- return 0;
+ return false;
// Get the parent byte size so we can verify any members will fit
const uint64_t parent_byte_size =
@@ -2697,7 +2466,7 @@ bool DWARFASTParserClang::ParseChildMembers(
ClangASTContext *ast =
llvm::dyn_cast_or_null<ClangASTContext>(class_clang_type.GetTypeSystem());
if (ast == nullptr)
- return 0;
+ return false;
for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
die = die.GetSibling()) {
@@ -2709,12 +2478,10 @@ bool DWARFASTParserClang::ParseChildMembers(
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes(attributes);
if (num_attributes > 0) {
- Declaration decl;
- // DWARFExpression location;
- const char *name = NULL;
- const char *prop_name = NULL;
- const char *prop_getter_name = NULL;
- const char *prop_setter_name = NULL;
+ const char *name = nullptr;
+ const char *prop_name = nullptr;
+ const char *prop_getter_name = nullptr;
+ const char *prop_setter_name = nullptr;
uint32_t prop_attributes = 0;
bool is_artificial = false;
@@ -2722,7 +2489,7 @@ bool DWARFASTParserClang::ParseChildMembers(
AccessType accessibility = eAccessNone;
uint32_t member_byte_offset =
(parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
- size_t byte_size = 0;
+ llvm::Optional<uint64_t> byte_size;
int64_t bit_offset = 0;
uint64_t data_bit_offset = UINT64_MAX;
size_t bit_size = 0;
@@ -2734,16 +2501,6 @@ bool DWARFASTParserClang::ParseChildMembers(
DWARFFormValue form_value;
if (attributes.ExtractFormValueAtIndex(i, form_value)) {
switch (attr) {
- case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
- break;
- case DW_AT_decl_line:
- decl.SetLine(form_value.Unsigned());
- break;
- case DW_AT_decl_column:
- decl.SetColumn(form_value.Unsigned());
- break;
case DW_AT_name:
name = form_value.AsCString();
break;
@@ -2776,7 +2533,8 @@ bool DWARFASTParserClang::ParseChildMembers(
module_sp, debug_info_data, die.GetCU(), block_offset,
block_length, eRegisterKindDWARF, &initialValue,
nullptr, memberOffset, nullptr)) {
- member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
+ member_byte_offset =
+ memberOffset.ResolveValue(nullptr).UInt();
}
} else {
// With DWARF 3 and later, if the value is an integer constant,
@@ -2865,7 +2623,7 @@ bool DWARFASTParserClang::ParseChildMembers(
// with a crash if we try to use this type in an expression when clang
// becomes unhappy with its recycled debug info.
- if (byte_size == 0 && bit_offset < 0) {
+ if (byte_size.getValueOr(0) == 0 && bit_offset < 0) {
bit_size = 0;
bit_offset = 0;
}
@@ -2877,7 +2635,7 @@ bool DWARFASTParserClang::ParseChildMembers(
// Handle static members
if (is_external && member_byte_offset == UINT32_MAX) {
- Type *var_type = die.ResolveTypeUID(DIERef(encoding_form));
+ Type *var_type = die.ResolveTypeUID(encoding_form.Reference());
if (var_type) {
if (accessibility == eAccessNone)
@@ -2890,9 +2648,9 @@ bool DWARFASTParserClang::ParseChildMembers(
}
if (!is_artificial) {
- Type *member_type = die.ResolveTypeUID(DIERef(encoding_form));
+ Type *member_type = die.ResolveTypeUID(encoding_form.Reference());
- clang::FieldDecl *field_decl = NULL;
+ clang::FieldDecl *field_decl = nullptr;
if (tag == DW_TAG_member) {
if (member_type) {
if (accessibility == eAccessNone)
@@ -2927,12 +2685,12 @@ bool DWARFASTParserClang::ParseChildMembers(
if (data_bit_offset != UINT64_MAX) {
this_field_info.bit_offset = data_bit_offset;
} else {
- if (byte_size == 0)
+ if (!byte_size)
byte_size = member_type->GetByteSize();
ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
if (objfile->GetByteOrder() == eByteOrderLittle) {
- this_field_info.bit_offset += byte_size * 8;
+ this_field_info.bit_offset += byte_size.getValueOr(0) * 8;
this_field_info.bit_offset -= (bit_offset + bit_size);
} else {
this_field_info.bit_offset += bit_offset;
@@ -2945,13 +2703,12 @@ bool DWARFASTParserClang::ParseChildMembers(
ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
objfile->GetModule()->ReportWarning(
"0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid "
- "bit offset (0x%8.8" PRIx64
+ "bit offset (0x%8.8" PRIx64
") member will be ignored. Please file a bug against the "
"compiler and include the preprocessed output for %s\n",
die.GetID(), DW_TAG_value_to_name(tag), name,
this_field_info.bit_offset,
- sc.comp_unit ? sc.comp_unit->GetPath().c_str()
- : "the source file");
+ GetUnitName(parent_die).c_str());
this_field_info.Clear();
continue;
}
@@ -3074,9 +2831,10 @@ bool DWARFASTParserClang::ParseChildMembers(
member_byte_offset > parent_byte_size)) {
module_sp->ReportError(
"0x%8.8" PRIx64
- ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64
+ ": DW_TAG_member '%s' refers to type 0x%8.8x"
" which extends beyond the bounds of 0x%8.8" PRIx64,
- die.GetID(), name, encoding_form.Reference(),
+ die.GetID(), name,
+ encoding_form.Reference().GetOffset(),
parent_die.GetID());
}
@@ -3103,9 +2861,7 @@ bool DWARFASTParserClang::ParseChildMembers(
"complete definition.\nPlease file a bug against the "
"compiler and include the preprocessed output for %s",
parent_die.GetOffset(), parent_die.GetName(),
- die.GetOffset(), name,
- sc.comp_unit ? sc.comp_unit->GetPath().c_str()
- : "the source file");
+ die.GetOffset(), name, GetUnitName(parent_die).c_str());
// We have no choice other than to pretend that the member
// class is complete. If we don't do this, clang will crash
// when trying to layout the class. Since we provide layout
@@ -3139,24 +2895,23 @@ bool DWARFASTParserClang::ParseChildMembers(
if (name)
module_sp->ReportError(
"0x%8.8" PRIx64
- ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64
+ ": DW_TAG_member '%s' refers to type 0x%8.8x"
" which was unable to be parsed",
- die.GetID(), name, encoding_form.Reference());
+ die.GetID(), name, encoding_form.Reference().GetOffset());
else
module_sp->ReportError(
- "0x%8.8" PRIx64
- ": DW_TAG_member refers to type 0x%8.8" PRIx64
+ "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x"
" which was unable to be parsed",
- die.GetID(), encoding_form.Reference());
+ die.GetID(), encoding_form.Reference().GetOffset());
}
}
- if (prop_name != NULL && member_type) {
- clang::ObjCIvarDecl *ivar_decl = NULL;
+ if (prop_name != nullptr && member_type) {
+ clang::ObjCIvarDecl *ivar_decl = nullptr;
if (field_decl) {
ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
- assert(ivar_decl != NULL);
+ assert(ivar_decl != nullptr);
}
ClangASTMetadata metadata;
@@ -3177,7 +2932,7 @@ bool DWARFASTParserClang::ParseChildMembers(
case DW_TAG_subprogram:
// Let the type parsing code handle this one for us.
- member_function_dies.Append(die);
+ member_function_dies.push_back(die);
break;
case DW_TAG_inheritance: {
@@ -3188,8 +2943,6 @@ bool DWARFASTParserClang::ParseChildMembers(
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes(attributes);
if (num_attributes > 0) {
- Declaration decl;
- DWARFExpression location(die.GetCU());
DWARFFormValue encoding_form;
AccessType accessibility = default_accessibility;
bool is_virtual = false;
@@ -3201,16 +2954,6 @@ bool DWARFASTParserClang::ParseChildMembers(
DWARFFormValue form_value;
if (attributes.ExtractFormValueAtIndex(i, form_value)) {
switch (attr) {
- case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
- break;
- case DW_AT_decl_line:
- decl.SetLine(form_value.Unsigned());
- break;
- case DW_AT_decl_column:
- decl.SetColumn(form_value.Unsigned());
- break;
case DW_AT_type:
encoding_form = form_value;
break;
@@ -3227,7 +2970,8 @@ bool DWARFASTParserClang::ParseChildMembers(
block_offset, block_length,
eRegisterKindDWARF, &initialValue,
nullptr, memberOffset, nullptr)) {
- member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
+ member_byte_offset =
+ memberOffset.ResolveValue(nullptr).UInt();
}
} else {
// With DWARF 3 and later, if the value is an integer constant,
@@ -3254,14 +2998,15 @@ bool DWARFASTParserClang::ParseChildMembers(
}
}
- Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form));
- if (base_class_type == NULL) {
+ Type *base_class_type = die.ResolveTypeUID(encoding_form.Reference());
+ if (base_class_type == nullptr) {
module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to "
- "resolve the base class at 0x%8.8" PRIx64
+ "resolve the base class at 0x%8.8x"
" from enclosing type 0x%8.8x. \nPlease file "
"a bug and attach the file at the start of "
"this error message",
- die.GetOffset(), encoding_form.Reference(),
+ die.GetOffset(),
+ encoding_form.Reference().GetOffset(),
parent_die.GetOffset());
break;
}
@@ -3313,10 +3058,9 @@ bool DWARFASTParserClang::ParseChildMembers(
}
size_t DWARFASTParserClang::ParseChildParameters(
- CompileUnit &comp_unit, clang::DeclContext *containing_decl_ctx,
- const DWARFDIE &parent_die, bool skip_artificial, bool &is_static,
- bool &is_variadic, bool &has_template_params,
- std::vector<CompilerType> &function_param_types,
+ clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die,
+ bool skip_artificial, bool &is_static, bool &is_variadic,
+ bool &has_template_params, std::vector<CompilerType> &function_param_types,
std::vector<clang::ParmVarDecl *> &function_param_decls,
unsigned &type_quals) {
if (!parent_die)
@@ -3331,8 +3075,7 @@ size_t DWARFASTParserClang::ParseChildParameters(
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes(attributes);
if (num_attributes > 0) {
- const char *name = NULL;
- Declaration decl;
+ const char *name = nullptr;
DWARFFormValue param_type_die_form;
bool is_artificial = false;
// one of None, Auto, Register, Extern, Static, PrivateExtern
@@ -3344,16 +3087,6 @@ size_t DWARFASTParserClang::ParseChildParameters(
DWARFFormValue form_value;
if (attributes.ExtractFormValueAtIndex(i, form_value)) {
switch (attr) {
- case DW_AT_decl_file:
- decl.SetFile(comp_unit.GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
- break;
- case DW_AT_decl_line:
- decl.SetLine(form_value.Unsigned());
- break;
- case DW_AT_decl_column:
- decl.SetColumn(form_value.Unsigned());
- break;
case DW_AT_name:
name = form_value.AsCString();
break;
@@ -3388,8 +3121,9 @@ size_t DWARFASTParserClang::ParseChildParameters(
// Often times compilers omit the "this" name for the
// specification DIEs, so we can't rely upon the name being in
// the formal parameter DIE...
- (name == NULL || ::strcmp(name, "this") == 0)) {
- Type *this_type = die.ResolveTypeUID(DIERef(param_type_die_form));
+ (name == nullptr || ::strcmp(name, "this") == 0)) {
+ Type *this_type =
+ die.ResolveTypeUID(param_type_die_form.Reference());
if (this_type) {
uint32_t encoding_mask = this_type->GetEncodingMask();
if (encoding_mask & Type::eEncodingIsPointerUID) {
@@ -3406,7 +3140,7 @@ size_t DWARFASTParserClang::ParseChildParameters(
}
if (!skip) {
- Type *type = die.ResolveTypeUID(DIERef(param_type_die_form));
+ Type *type = die.ResolveTypeUID(param_type_die_form.Reference());
if (type) {
function_param_types.push_back(type->GetForwardCompilerType());
@@ -3554,7 +3288,7 @@ Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) {
if (attr == DW_AT_type &&
attributes.ExtractFormValueAtIndex(i, form_value))
- return dwarf->ResolveTypeUID(dwarf->GetDIE(DIERef(form_value)), true);
+ return dwarf->ResolveTypeUID(form_value.Reference(), true);
}
}
}
@@ -3799,8 +3533,11 @@ DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) {
const char *namespace_name = die.GetName();
clang::DeclContext *containing_decl_ctx =
GetClangDeclContextContainingDIE(die, nullptr);
- namespace_decl = m_ast.GetUniqueNamespaceDeclaration(namespace_name,
- containing_decl_ctx);
+ bool is_inline =
+ die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0;
+
+ namespace_decl = m_ast.GetUniqueNamespaceDeclaration(
+ namespace_name, containing_decl_ctx, is_inline);
Log *log =
nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
if (log) {
@@ -3870,7 +3607,7 @@ void DWARFASTParserClang::LinkDeclContextToDIE(clang::DeclContext *decl_ctx,
bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die,
- lldb_private::Type *class_type, DWARFDIECollection &failures) {
+ lldb_private::Type *class_type, std::vector<DWARFDIE> &failures) {
if (!class_type || !src_class_die || !dst_class_die)
return false;
if (src_class_die.Tag() != dst_class_die.Tag())
@@ -4075,7 +3812,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
log->Printf("warning: couldn't find a match for 0x%8.8x",
dst_die.GetOffset());
- failures.Append(dst_die);
+ failures.push_back(dst_die);
}
}
}
@@ -4140,9 +3877,9 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
"method '%s'",
dst_die.GetOffset(), dst_name_artificial.GetCString());
- failures.Append(dst_die);
+ failures.push_back(dst_die);
}
}
- return (failures.Size() != 0);
+ return !failures.empty();
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 63e058d7bf21..5b5d83d65932 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -1,9 +1,8 @@
//===-- DWARFASTParserClang.h -----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -22,11 +21,12 @@
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangASTImporter.h"
+#include <vector>
+
namespace lldb_private {
class CompileUnit;
}
class DWARFDebugInfoEntry;
-class DWARFDIECollection;
class SymbolFileDWARF;
class DWARFASTParserClang : public DWARFASTParser {
@@ -81,19 +81,17 @@ protected:
&template_param_infos);
bool ParseChildMembers(
- const lldb_private::SymbolContext &sc, const DWARFDIE &die,
- lldb_private::CompilerType &class_compiler_type,
+ const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type,
const lldb::LanguageType class_language,
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
std::vector<int> &member_accessibilities,
- DWARFDIECollection &member_function_dies,
+ std::vector<DWARFDIE> &member_function_dies,
DelayedPropertyList &delayed_properties,
lldb::AccessType &default_accessibility, bool &is_a_class,
lldb_private::ClangASTImporter::LayoutInfo &layout_info);
size_t
- ParseChildParameters(lldb_private::CompileUnit &comp_unit,
- clang::DeclContext *containing_decl_ctx,
+ ParseChildParameters(clang::DeclContext *containing_decl_ctx,
const DWARFDIE &parent_die, bool skip_artificial,
bool &is_static, bool &is_variadic,
bool &has_template_params,
@@ -101,8 +99,7 @@ protected:
std::vector<clang::ParmVarDecl *> &function_param_decls,
unsigned &type_quals);
- size_t ParseChildEnumerators(const lldb_private::SymbolContext &sc,
- lldb_private::CompilerType &compiler_type,
+ size_t ParseChildEnumerators(lldb_private::CompilerType &compiler_type,
bool is_signed, uint32_t enumerator_byte_size,
const DWARFDIE &parent_die);
@@ -118,7 +115,7 @@ protected:
bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die,
const DWARFDIE &dst_class_die,
lldb_private::Type *class_type,
- DWARFDIECollection &failures);
+ std::vector<DWARFDIE> &failures);
clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die);
@@ -128,10 +125,8 @@ protected:
lldb::TypeSP ParseTypeFromDWO(const DWARFDIE &die, lldb_private::Log *log);
- //----------------------------------------------------------------------
// Return true if this type is a declaration to a type in an external
// module.
- //----------------------------------------------------------------------
lldb::ModuleSP GetModuleForType(const DWARFDIE &die);
typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
@@ -150,7 +145,7 @@ protected:
DeclToDIEMap m_decl_to_die;
DIEToDeclContextMap m_die_to_decl_ctx;
DeclContextToDIEMap m_decl_ctx_to_die;
- std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap;
+ std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
};
#endif // SymbolFileDWARF_DWARFASTParserClang_h_
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
index d78b9ab10f5a..6128163a2926 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -1,9 +1,8 @@
//===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -12,6 +11,8 @@
#include "lldb/Core/dwarf.h"
#include "lldb/Utility/Stream.h"
+#include "llvm/Object/Error.h"
+
#include "DWARFFormValue.h"
using namespace lldb_private;
@@ -24,57 +25,46 @@ DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag,
: m_code(InvalidCode), m_tag(tag), m_has_children(has_children),
m_attributes() {}
-bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr) {
- return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
-}
+llvm::Expected<DWARFEnumState>
+DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ m_code = data.GetULEB128(offset_ptr);
+ if (m_code == 0)
+ return DWARFEnumState::Complete;
-bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr,
- dw_uleb128_t code) {
- m_code = code;
m_attributes.clear();
- if (m_code) {
- m_tag = data.GetULEB128(offset_ptr);
- m_has_children = data.GetU8(offset_ptr);
-
- while (data.ValidOffset(*offset_ptr)) {
- dw_attr_t attr = data.GetULEB128(offset_ptr);
- dw_form_t form = data.GetULEB128(offset_ptr);
- DWARFFormValue::ValueType val;
-
- if (form == DW_FORM_implicit_const)
- val.value.sval = data.GetULEB128(offset_ptr);
-
- if (attr && form)
- m_attributes.push_back(DWARFAttribute(attr, form, val));
- else
- break;
- }
-
- return m_tag != 0;
- } else {
- m_tag = 0;
- m_has_children = 0;
- }
+ m_tag = data.GetULEB128(offset_ptr);
+ if (m_tag == DW_TAG_null)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "abbrev decl requires non-null tag.");
- return false;
-}
+ m_has_children = data.GetU8(offset_ptr);
-void DWARFAbbreviationDeclaration::Dump(Stream *s) const {
- s->Printf("Debug Abbreviation Declaration: code = 0x%4.4x, tag = %s, "
- "has_children = %s\n",
- m_code, DW_TAG_value_to_name(m_tag),
- DW_CHILDREN_value_to_name(m_has_children));
+ while (data.ValidOffset(*offset_ptr)) {
+ dw_attr_t attr = data.GetULEB128(offset_ptr);
+ dw_form_t form = data.GetULEB128(offset_ptr);
- DWARFAttribute::const_iterator pos;
+ // This is the last attribute for this abbrev decl, but there may still be
+ // more abbrev decls, so return MoreItems to indicate to the caller that
+ // they should call this function again.
+ if (!attr && !form)
+ return DWARFEnumState::MoreItems;
- for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos)
- s->Printf(" attr = %s, form = %s\n",
- DW_AT_value_to_name(pos->get_attr()),
- DW_FORM_value_to_name(pos->get_form()));
+ if (!attr || !form)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "malformed abbreviation declaration attribute");
+
+ DWARFFormValue::ValueType val;
+
+ if (form == DW_FORM_implicit_const)
+ val.value.sval = data.GetULEB128(offset_ptr);
+
+ m_attributes.push_back(DWARFAttribute(attr, form, val));
+ }
- s->Printf("\n");
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "abbreviation declaration attribute list not terminated with a null "
+ "entry");
}
bool DWARFAbbreviationDeclaration::IsValid() {
@@ -95,5 +85,5 @@ DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const {
bool DWARFAbbreviationDeclaration::
operator==(const DWARFAbbreviationDeclaration &rhs) const {
return Tag() == rhs.Tag() && HasChildren() == rhs.HasChildren() &&
- Attributes() == rhs.Attributes();
+ m_attributes == rhs.m_attributes;
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
index afce52558f45..c0cf8823a368 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
@@ -1,9 +1,8 @@
//===-- DWARFAbbreviationDeclaration.h --------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,7 +10,9 @@
#define liblldb_DWARFAbbreviationDeclaration_h_
#include "DWARFAttribute.h"
+#include "DWARFDefines.h"
#include "SymbolFileDWARF.h"
+#include "llvm/Support/Error.h"
class DWARFAbbreviationDeclaration {
public:
@@ -20,18 +21,12 @@ public:
// For hand crafting an abbreviation declaration
DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children);
- void AddAttribute(const DWARFAttribute &attr) {
- m_attributes.push_back(attr);
- }
dw_uleb128_t Code() const { return m_code; }
void SetCode(dw_uleb128_t code) { m_code = code; }
dw_tag_t Tag() const { return m_tag; }
bool HasChildren() const { return m_has_children; }
size_t NumAttributes() const { return m_attributes.size(); }
- dw_attr_t GetAttrByIndex(uint32_t idx) const {
- return m_attributes.size() > idx ? m_attributes[idx].get_attr() : 0;
- }
dw_form_t GetFormByIndex(uint32_t idx) const {
return m_attributes.size() > idx ? m_attributes[idx].get_form() : 0;
}
@@ -45,14 +40,20 @@ public:
return m_attributes[idx].get_form();
}
uint32_t FindAttributeIndex(dw_attr_t attr) const;
- bool Extract(const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr);
- bool Extract(const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr, dw_uleb128_t code);
+
+ /// Extract one abbreviation declaration and all of its associated attributes.
+ /// Possible return values:
+ /// DWARFEnumState::Complete - the extraction completed successfully. This
+ /// was the last abbrev decl in a sequence, and the user should not call
+ /// this function again.
+ /// DWARFEnumState::MoreItems - the extraction completed successfully. The
+ /// user should call this function again to retrieve the next decl.
+ /// llvm::Error - A parsing error occurred. The debug info is malformed.
+ llvm::Expected<lldb_private::DWARFEnumState>
+ extract(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
bool IsValid();
- void Dump(lldb_private::Stream *s) const;
bool operator==(const DWARFAbbreviationDeclaration &rhs) const;
- const DWARFAttribute::collection &Attributes() const { return m_attributes; }
protected:
dw_uleb128_t m_code;
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
index dd830eb7b9dd..b3594a455680 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
@@ -1,9 +1,8 @@
//===-- DWARFAttribute.cpp --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -33,41 +32,27 @@ void DWARFAttributes::Append(const DWARFUnit *cu, dw_offset_t attr_die_offset,
m_infos.push_back(attr_value);
}
-bool DWARFAttributes::ContainsAttribute(dw_attr_t attr) const {
- return FindAttributeIndex(attr) != UINT32_MAX;
-}
-
-bool DWARFAttributes::RemoveAttribute(dw_attr_t attr) {
- uint32_t attr_index = FindAttributeIndex(attr);
- if (attr_index != UINT32_MAX) {
- m_infos.erase(m_infos.begin() + attr_index);
- return true;
- }
- return false;
-}
-
bool DWARFAttributes::ExtractFormValueAtIndex(
uint32_t i, DWARFFormValue &form_value) const {
const DWARFUnit *cu = CompileUnitAtIndex(i);
- form_value.SetCompileUnit(cu);
+ form_value.SetUnit(cu);
form_value.SetForm(FormAtIndex(i));
lldb::offset_t offset = DIEOffsetAtIndex(i);
return form_value.ExtractValue(cu->GetData(), &offset);
}
-uint64_t DWARFAttributes::FormValueAsUnsigned(dw_attr_t attr,
- uint64_t fail_value) const {
+DWARFDIE
+DWARFAttributes::FormValueAsReference(dw_attr_t attr) const {
const uint32_t attr_idx = FindAttributeIndex(attr);
if (attr_idx != UINT32_MAX)
- return FormValueAsUnsignedAtIndex(attr_idx, fail_value);
- return fail_value;
+ return FormValueAsReferenceAtIndex(attr_idx);
+ return {};
}
-uint64_t
-DWARFAttributes::FormValueAsUnsignedAtIndex(uint32_t i,
- uint64_t fail_value) const {
+DWARFDIE
+DWARFAttributes::FormValueAsReferenceAtIndex(uint32_t i) const {
DWARFFormValue form_value;
if (ExtractFormValueAtIndex(i, form_value))
return form_value.Reference();
- return fail_value;
+ return {};
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
index 2399861d7fc3..58427b19100a 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
@@ -1,9 +1,8 @@
//===-- DWARFAttribute.h ----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -27,8 +26,6 @@ public:
m_attr = attr;
m_form = form;
}
- void set_attr(dw_attr_t attr) { m_attr = attr; }
- void set_form(dw_form_t form) { m_form = form; }
dw_attr_t get_attr() const { return m_attr; }
dw_form_t get_form() const { return m_form; }
void get(dw_attr_t &attr, dw_form_t &form,
@@ -68,11 +65,9 @@ public:
}
dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].attr.get_form(); }
bool ExtractFormValueAtIndex(uint32_t i, DWARFFormValue &form_value) const;
- uint64_t FormValueAsUnsignedAtIndex(uint32_t i, uint64_t fail_value) const;
- uint64_t FormValueAsUnsigned(dw_attr_t attr, uint64_t fail_value) const;
+ DWARFDIE FormValueAsReferenceAtIndex(uint32_t i) const;
+ DWARFDIE FormValueAsReference(dw_attr_t attr) const;
uint32_t FindAttributeIndex(dw_attr_t attr) const;
- bool ContainsAttribute(dw_attr_t attr) const;
- bool RemoveAttribute(dw_attr_t attr);
void Clear() { m_infos.clear(); }
size_t Size() const { return m_infos.size(); }
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
index 077de9604f1d..96adb72c9532 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -1,9 +1,8 @@
//===-- DWARFBaseDIE.cpp ---------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -18,14 +17,12 @@
using namespace lldb_private;
-DIERef DWARFBaseDIE::GetDIERef() const {
+llvm::Optional<DIERef> DWARFBaseDIE::GetDIERef() const {
if (!IsValid())
- return DIERef();
+ return llvm::None;
- dw_offset_t cu_offset = m_cu->GetOffset();
- if (m_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
- cu_offset = m_cu->GetBaseObjOffset();
- return DIERef(cu_offset, m_die->GetOffset());
+ return DIERef(m_cu->GetSymbolFileDWARF().GetDwoNum(), m_cu->GetDebugSection(),
+ m_die->GetOffset());
}
dw_tag_t DWARFBaseDIE::Tag() const {
@@ -42,8 +39,7 @@ const char *DWARFBaseDIE::GetTagAsCString() const {
const char *DWARFBaseDIE::GetAttributeValueAsString(const dw_attr_t attr,
const char *fail_value) const {
if (IsValid())
- return m_die->GetAttributeValueAsString(GetDWARF(), GetCU(), attr,
- fail_value);
+ return m_die->GetAttributeValueAsString(GetCU(), attr, fail_value);
else
return fail_value;
}
@@ -51,26 +47,7 @@ const char *DWARFBaseDIE::GetAttributeValueAsString(const dw_attr_t attr,
uint64_t DWARFBaseDIE::GetAttributeValueAsUnsigned(const dw_attr_t attr,
uint64_t fail_value) const {
if (IsValid())
- return m_die->GetAttributeValueAsUnsigned(GetDWARF(), GetCU(), attr,
- fail_value);
- else
- return fail_value;
-}
-
-int64_t DWARFBaseDIE::GetAttributeValueAsSigned(const dw_attr_t attr,
- int64_t fail_value) const {
- if (IsValid())
- return m_die->GetAttributeValueAsSigned(GetDWARF(), GetCU(), attr,
- fail_value);
- else
- return fail_value;
-}
-
-uint64_t DWARFBaseDIE::GetAttributeValueAsReference(const dw_attr_t attr,
- uint64_t fail_value) const {
- if (IsValid())
- return m_die->GetAttributeValueAsReference(GetDWARF(), GetCU(), attr,
- fail_value);
+ return m_die->GetAttributeValueAsUnsigned(GetCU(), attr, fail_value);
else
return fail_value;
}
@@ -78,19 +55,20 @@ uint64_t DWARFBaseDIE::GetAttributeValueAsReference(const dw_attr_t attr,
uint64_t DWARFBaseDIE::GetAttributeValueAsAddress(const dw_attr_t attr,
uint64_t fail_value) const {
if (IsValid())
- return m_die->GetAttributeValueAsAddress(GetDWARF(), GetCU(), attr,
- fail_value);
+ return m_die->GetAttributeValueAsAddress(GetCU(), attr, fail_value);
else
return fail_value;
}
lldb::user_id_t DWARFBaseDIE::GetID() const {
- return GetDIERef().GetUID(GetDWARF());
+ if (IsValid())
+ return GetDWARF()->GetUID(*this);
+ return LLDB_INVALID_UID;
}
const char *DWARFBaseDIE::GetName() const {
if (IsValid())
- return m_die->GetName(GetDWARF(), m_cu);
+ return m_die->GetName(m_cu);
else
return nullptr;
}
@@ -110,13 +88,6 @@ lldb::ModuleSP DWARFBaseDIE::GetModule() const {
return lldb::ModuleSP();
}
-lldb_private::CompileUnit *DWARFBaseDIE::GetLLDBCompileUnit() const {
- if (IsValid())
- return GetDWARF()->GetCompUnitForDWARFCompUnit(GetCU());
- else
- return nullptr;
-}
-
dw_offset_t DWARFBaseDIE::GetOffset() const {
if (IsValid())
return m_die->GetOffset();
@@ -124,16 +95,9 @@ dw_offset_t DWARFBaseDIE::GetOffset() const {
return DW_INVALID_OFFSET;
}
-dw_offset_t DWARFBaseDIE::GetCompileUnitRelativeOffset() const {
- if (IsValid())
- return m_die->GetOffset() - m_cu->GetOffset();
- else
- return DW_INVALID_OFFSET;
-}
-
SymbolFileDWARF *DWARFBaseDIE::GetDWARF() const {
if (m_cu)
- return m_cu->GetSymbolFileDWARF();
+ return &m_cu->GetSymbolFileDWARF();
else
return nullptr;
}
@@ -163,21 +127,13 @@ bool DWARFBaseDIE::Supports_DW_AT_APPLE_objc_complete_type() const {
size_t DWARFBaseDIE::GetAttributes(DWARFAttributes &attributes,
uint32_t depth) const {
- if (IsValid()) {
- return m_die->GetAttributes(m_cu, m_cu->GetFixedFormSizes(), attributes,
- depth);
- }
+ if (IsValid())
+ return m_die->GetAttributes(m_cu, attributes, depth);
if (depth == 0)
attributes.Clear();
return 0;
}
-void DWARFBaseDIE::Dump(lldb_private::Stream *s,
- const uint32_t recurse_depth) const {
- if (s && IsValid())
- m_die->Dump(GetDWARF(), GetCU(), *s, recurse_depth);
-}
-
bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs) {
return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU();
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
index 2163a027ffbc..0058043017cd 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -1,9 +1,8 @@
//===-- DWARFBaseDIE.h -----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -13,13 +12,12 @@
#include "lldb/Core/dwarf.h"
#include "lldb/lldb-types.h"
-struct DIERef;
+class DIERef;
class DWARFASTParser;
class DWARFAttributes;
class DWARFUnit;
class DWARFDebugInfoEntry;
class DWARFDeclContext;
-class DWARFDIECollection;
class SymbolFileDWARF;
class DWARFBaseDIE {
@@ -39,9 +37,7 @@ public:
: m_cu(const_cast<DWARFUnit *>(cu)),
m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
- //----------------------------------------------------------------------
// Tests
- //----------------------------------------------------------------------
explicit operator bool() const { return IsValid(); }
bool IsValid() const { return m_cu && m_die; }
@@ -50,16 +46,14 @@ public:
bool Supports_DW_AT_APPLE_objc_complete_type() const;
- //----------------------------------------------------------------------
// Accessors
- //----------------------------------------------------------------------
SymbolFileDWARF *GetDWARF() const;
DWARFUnit *GetCU() const { return m_cu; }
DWARFDebugInfoEntry *GetDIE() const { return m_die; }
- DIERef GetDIERef() const;
+ llvm::Optional<DIERef> GetDIERef() const;
lldb_private::TypeSystem *GetTypeSystem() const;
@@ -79,33 +73,25 @@ public:
m_die = nullptr;
}
- //----------------------------------------------------------------------
// Get the data that contains the attribute values for this DIE. Support
// for .debug_types means that any DIE can have its data either in the
// .debug_info or the .debug_types section; this method will return the
// correct section data.
//
// Clients must validate that this object is valid before calling this.
- //----------------------------------------------------------------------
const lldb_private::DWARFDataExtractor &GetData() const;
- //----------------------------------------------------------------------
// Accessing information about a DIE
- //----------------------------------------------------------------------
dw_tag_t Tag() const;
const char *GetTagAsCString() const;
dw_offset_t GetOffset() const;
- dw_offset_t GetCompileUnitRelativeOffset() const;
-
- //----------------------------------------------------------------------
// Get the LLDB user ID for this DIE. This is often just the DIE offset,
// but it might have a SymbolFileDWARF::GetID() in the high 32 bits if
// we are doing Darwin DWARF in .o file, or DWARF stand alone debug
// info.
- //----------------------------------------------------------------------
lldb::user_id_t GetID() const;
const char *GetName() const;
@@ -114,38 +100,22 @@ public:
lldb::ModuleSP GetModule() const;
- lldb_private::CompileUnit *GetLLDBCompileUnit() const;
-
- //----------------------------------------------------------------------
// Getting attribute values from the DIE.
//
// GetAttributeValueAsXXX() functions should only be used if you are
// looking for one or two attributes on a DIE. If you are trying to
// parse all attributes, use GetAttributes (...) instead
- //----------------------------------------------------------------------
const char *GetAttributeValueAsString(const dw_attr_t attr,
const char *fail_value) const;
uint64_t GetAttributeValueAsUnsigned(const dw_attr_t attr,
uint64_t fail_value) const;
- int64_t GetAttributeValueAsSigned(const dw_attr_t attr,
- int64_t fail_value) const;
-
- uint64_t GetAttributeValueAsReference(const dw_attr_t attr,
- uint64_t fail_value) const;
-
uint64_t GetAttributeValueAsAddress(const dw_attr_t attr,
uint64_t fail_value) const;
size_t GetAttributes(DWARFAttributes &attributes, uint32_t depth = 0) const;
- //----------------------------------------------------------------------
- // Pretty printing
- //----------------------------------------------------------------------
-
- void Dump(lldb_private::Stream *s, const uint32_t recurse_depth) const;
-
protected:
DWARFUnit *m_cu;
DWARFDebugInfoEntry *m_die;
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index b9a7231286e3..718f0537d6ed 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -1,98 +1,115 @@
//===-- DWARFCompileUnit.cpp ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DWARFCompileUnit.h"
+#include "DWARFDebugAranges.h"
+#include "SymbolFileDWARFDebugMap.h"
-#include "SymbolFileDWARF.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Utility/Stream.h"
using namespace lldb;
using namespace lldb_private;
-extern int g_verbose;
-
-DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data)
- : DWARFUnit(dwarf2Data) {}
-
-DWARFUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
- const DWARFDataExtractor &debug_info,
- lldb::offset_t *offset_ptr) {
- // std::make_shared would require the ctor to be public.
- std::shared_ptr<DWARFCompileUnit> cu_sp(new DWARFCompileUnit(dwarf2Data));
-
- cu_sp->m_offset = *offset_ptr;
-
- if (debug_info.ValidOffset(*offset_ptr)) {
- dw_offset_t abbr_offset;
- const DWARFDebugAbbrev *abbr = dwarf2Data->DebugAbbrev();
- cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr);
- cu_sp->m_is_dwarf64 = debug_info.IsDWARF64();
- cu_sp->m_version = debug_info.GetU16(offset_ptr);
-
- if (cu_sp->m_version == 5) {
- cu_sp->m_unit_type = debug_info.GetU8(offset_ptr);
- cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
- abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
-
- if (cu_sp->m_unit_type == llvm::dwarf::DW_UT_skeleton)
- cu_sp->m_dwo_id = debug_info.GetU64(offset_ptr);
- } else {
- abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
- cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
- }
-
- bool length_OK =
- debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1);
- bool version_OK = SymbolFileDWARF::SupportedVersion(cu_sp->m_version);
- bool abbr_offset_OK =
- dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset);
- bool addr_size_OK = (cu_sp->m_addr_size == 4) || (cu_sp->m_addr_size == 8);
-
- if (length_OK && version_OK && addr_size_OK && abbr_offset_OK &&
- abbr != NULL) {
- cu_sp->m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
- return cu_sp;
- }
-
- // reset the offset to where we tried to parse from if anything went wrong
- *offset_ptr = cu_sp->m_offset;
- }
-
- return nullptr;
-}
-
void DWARFCompileUnit::Dump(Stream *s) const {
s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, "
"abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at "
"{0x%8.8x})\n",
- m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size,
- GetNextCompileUnitOffset());
+ GetOffset(), GetLength(), GetVersion(), GetAbbrevOffset(),
+ GetAddressByteSize(), GetNextUnitOffset());
}
-uint32_t DWARFCompileUnit::GetHeaderByteSize() const {
- if (m_version < 5)
- return m_is_dwarf64 ? 23 : 11;
-
- switch (m_unit_type) {
- case llvm::dwarf::DW_UT_compile:
- case llvm::dwarf::DW_UT_partial:
- return 12;
- case llvm::dwarf::DW_UT_skeleton:
- case llvm::dwarf::DW_UT_split_compile:
- return 20;
- case llvm::dwarf::DW_UT_type:
- case llvm::dwarf::DW_UT_split_type:
- return 24;
+void DWARFCompileUnit::BuildAddressRangeTable(
+ DWARFDebugAranges *debug_aranges) {
+ // This function is usually called if there in no .debug_aranges section in
+ // order to produce a compile unit level set of address ranges that is
+ // accurate.
+
+ size_t num_debug_aranges = debug_aranges->GetNumRanges();
+
+ // First get the compile unit DIE only and check if it has a DW_AT_ranges
+ const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
+
+ const dw_offset_t cu_offset = GetOffset();
+ if (die) {
+ DWARFRangeList ranges;
+ const size_t num_ranges =
+ die->GetAttributeAddressRanges(this, ranges, false);
+ if (num_ranges > 0) {
+ // This compile unit has DW_AT_ranges, assume this is correct if it is
+ // present since clang no longer makes .debug_aranges by default and it
+ // emits DW_AT_ranges for DW_TAG_compile_units. GCC also does this with
+ // recent GCC builds.
+ for (size_t i = 0; i < num_ranges; ++i) {
+ const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
+ debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
+ range.GetRangeEnd());
+ }
+
+ return; // We got all of our ranges from the DW_AT_ranges attribute
+ }
+ }
+ // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF
+
+ // If the DIEs weren't parsed, then we don't want all dies for all compile
+ // units to stay loaded when they weren't needed. So we can end up parsing
+ // the DWARF and then throwing them all away to keep memory usage down.
+ ScopedExtractDIEs clear_dies(ExtractDIEsScoped());
+
+ die = DIEPtr();
+ if (die)
+ die->BuildAddressRangeTable(this, debug_aranges);
+
+ if (debug_aranges->GetNumRanges() == num_debug_aranges) {
+ // We got nothing from the functions, maybe we have a line tables only
+ // situation. Check the line tables and build the arange table from this.
+ SymbolContext sc;
+ sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
+ if (sc.comp_unit) {
+ SymbolFileDWARFDebugMap *debug_map_sym_file =
+ m_dwarf.GetDebugMapSymfile();
+ if (debug_map_sym_file == nullptr) {
+ if (LineTable *line_table = sc.comp_unit->GetLineTable()) {
+ LineTable::FileAddressRanges file_ranges;
+ const bool append = true;
+ const size_t num_ranges =
+ line_table->GetContiguousFileAddressRanges(file_ranges, append);
+ for (uint32_t idx = 0; idx < num_ranges; ++idx) {
+ const LineTable::FileAddressRanges::Entry &range =
+ file_ranges.GetEntryRef(idx);
+ debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
+ range.GetRangeEnd());
+ }
+ }
+ } else
+ debug_map_sym_file->AddOSOARanges(&m_dwarf, debug_aranges);
+ }
}
- llvm_unreachable("invalid UnitType.");
-}
-const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const {
- return m_dwarf->get_debug_info_data();
+ if (debug_aranges->GetNumRanges() == num_debug_aranges) {
+ // We got nothing from the functions, maybe we have a line tables only
+ // situation. Check the line tables and build the arange table from this.
+ SymbolContext sc;
+ sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
+ if (sc.comp_unit) {
+ if (LineTable *line_table = sc.comp_unit->GetLineTable()) {
+ LineTable::FileAddressRanges file_ranges;
+ const bool append = true;
+ const size_t num_ranges =
+ line_table->GetContiguousFileAddressRanges(file_ranges, append);
+ for (uint32_t idx = 0; idx < num_ranges; ++idx) {
+ const LineTable::FileAddressRanges::Entry &range =
+ file_ranges.GetEntryRef(idx);
+ debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(),
+ range.GetRangeEnd());
+ }
+ }
+ }
+ }
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
index b92a155e0335..75647dbb082f 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -1,9 +1,8 @@
//===-- DWARFCompileUnit.h --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,35 +10,26 @@
#define SymbolFileDWARF_DWARFCompileUnit_h_
#include "DWARFUnit.h"
+#include "llvm/Support/Error.h"
class DWARFCompileUnit : public DWARFUnit {
public:
- static DWARFUnitSP Extract(SymbolFileDWARF *dwarf2Data,
- const lldb_private::DWARFDataExtractor &debug_info,
- lldb::offset_t *offset_ptr);
+ void BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) override;
+
void Dump(lldb_private::Stream *s) const override;
- //------------------------------------------------------------------
- /// Get the data that contains the DIE information for this unit.
- ///
- /// @return
- /// The correct data (.debug_types for DWARF 4 and earlier, and
- /// .debug_info for DWARF 5 and later) for the DIE information in
- /// this unit.
- //------------------------------------------------------------------
- const lldb_private::DWARFDataExtractor &GetData() const override;
-
- //------------------------------------------------------------------
- /// Get the size in bytes of the header.
- ///
- /// @return
- /// Byte size of the compile unit header
- //------------------------------------------------------------------
- uint32_t GetHeaderByteSize() const override;
+ static bool classof(const DWARFUnit *unit) { return !unit->IsTypeUnit(); }
private:
- DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
+ DWARFCompileUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
+ const DWARFUnitHeader &header,
+ const DWARFAbbreviationDeclarationSet &abbrevs,
+ DIERef::Section section)
+ : DWARFUnit(dwarf, uid, header, abbrevs, section) {}
+
DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit);
+
+ friend class DWARFUnit;
};
#endif // SymbolFileDWARF_DWARFCompileUnit_h_
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp
new file mode 100644
index 000000000000..eb307ce1cce1
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp
@@ -0,0 +1,138 @@
+//===-- DWARFContext.cpp ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFContext.h"
+
+#include "lldb/Core/Section.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static DWARFDataExtractor LoadSection(SectionList *section_list,
+ SectionType section_type) {
+ if (!section_list)
+ return DWARFDataExtractor();
+
+ auto section_sp = section_list->FindSectionByType(section_type, true);
+ if (!section_sp)
+ return DWARFDataExtractor();
+
+ DWARFDataExtractor data;
+ section_sp->GetSectionData(data);
+ return data;
+}
+
+const DWARFDataExtractor &
+DWARFContext::LoadOrGetSection(SectionType main_section_type,
+ llvm::Optional<SectionType> dwo_section_type,
+ SectionData &data) {
+ llvm::call_once(data.flag, [&] {
+ if (dwo_section_type && isDwo())
+ data.data = LoadSection(m_dwo_section_list, *dwo_section_type);
+ else
+ data.data = LoadSection(m_main_section_list, main_section_type);
+ });
+ return data.data;
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadAbbrevData() {
+ return LoadOrGetSection(eSectionTypeDWARFDebugAbbrev,
+ eSectionTypeDWARFDebugAbbrevDwo, m_data_debug_abbrev);
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadArangesData() {
+ return LoadOrGetSection(eSectionTypeDWARFDebugAranges, llvm::None,
+ m_data_debug_aranges);
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadAddrData() {
+ return LoadOrGetSection(eSectionTypeDWARFDebugAddr, llvm::None,
+ m_data_debug_addr);
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadDebugInfoData() {
+ return LoadOrGetSection(eSectionTypeDWARFDebugInfo,
+ eSectionTypeDWARFDebugInfoDwo, m_data_debug_info);
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadLineData() {
+ return LoadOrGetSection(eSectionTypeDWARFDebugLine, llvm::None,
+ m_data_debug_line);
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadLineStrData() {
+ return LoadOrGetSection(eSectionTypeDWARFDebugLineStr, llvm::None,
+ m_data_debug_line_str);
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadMacroData() {
+ return LoadOrGetSection(eSectionTypeDWARFDebugMacro, llvm::None,
+ m_data_debug_macro);
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadRangesData() {
+ return LoadOrGetSection(eSectionTypeDWARFDebugRanges, llvm::None,
+ m_data_debug_ranges);
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadRngListsData() {
+ return LoadOrGetSection(eSectionTypeDWARFDebugRngLists, llvm::None,
+ m_data_debug_rnglists);
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadStrData() {
+ return LoadOrGetSection(eSectionTypeDWARFDebugStr,
+ eSectionTypeDWARFDebugStrDwo, m_data_debug_str);
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadStrOffsetsData() {
+ return LoadOrGetSection(eSectionTypeDWARFDebugStrOffsets,
+ eSectionTypeDWARFDebugStrOffsetsDwo,
+ m_data_debug_str_offsets);
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadDebugTypesData() {
+ return LoadOrGetSection(eSectionTypeDWARFDebugTypes,
+ eSectionTypeDWARFDebugTypesDwo, m_data_debug_types);
+}
+
+llvm::DWARFContext &DWARFContext::GetAsLLVM() {
+ if (!m_llvm_context) {
+ llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> section_map;
+ uint8_t addr_size = 0;
+
+ auto AddSection = [&](Section &section) {
+ DataExtractor section_data;
+ section.GetSectionData(section_data);
+
+ // Set the address size the first time we see it.
+ if (addr_size == 0)
+ addr_size = section_data.GetByteSize();
+
+ llvm::StringRef data = llvm::toStringRef(section_data.GetData());
+ llvm::StringRef name = section.GetName().GetStringRef();
+ if (name.startswith("."))
+ name = name.drop_front();
+ section_map.try_emplace(
+ name, llvm::MemoryBuffer::getMemBuffer(data, name, false));
+ };
+
+ if (m_main_section_list) {
+ for (auto &section : *m_main_section_list)
+ AddSection(*section);
+ }
+
+ if (m_dwo_section_list) {
+ for (auto &section : *m_dwo_section_list)
+ AddSection(*section);
+ }
+
+ m_llvm_context = llvm::DWARFContext::create(section_map, addr_size);
+ }
+ return *m_llvm_context;
+}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h
new file mode 100644
index 000000000000..add042384039
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h
@@ -0,0 +1,74 @@
+//===-- DWARFContext.h ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H
+#define LLDB_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H
+
+#include "DWARFDataExtractor.h"
+#include "lldb/Core/Section.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/Support/Threading.h"
+#include <memory>
+
+namespace lldb_private {
+class DWARFContext {
+private:
+ SectionList *m_main_section_list;
+ SectionList *m_dwo_section_list;
+ mutable std::unique_ptr<llvm::DWARFContext> m_llvm_context;
+
+ struct SectionData {
+ llvm::once_flag flag;
+ DWARFDataExtractor data;
+ };
+
+ SectionData m_data_debug_abbrev;
+ SectionData m_data_debug_addr;
+ SectionData m_data_debug_aranges;
+ SectionData m_data_debug_info;
+ SectionData m_data_debug_line;
+ SectionData m_data_debug_line_str;
+ SectionData m_data_debug_macro;
+ SectionData m_data_debug_ranges;
+ SectionData m_data_debug_rnglists;
+ SectionData m_data_debug_str;
+ SectionData m_data_debug_str_offsets;
+ SectionData m_data_debug_types;
+
+ bool isDwo() { return m_dwo_section_list != nullptr; }
+
+ const DWARFDataExtractor &
+ LoadOrGetSection(lldb::SectionType main_section_type,
+ llvm::Optional<lldb::SectionType> dwo_section_type,
+ SectionData &data);
+
+public:
+ explicit DWARFContext(SectionList *main_section_list,
+ SectionList *dwo_section_list)
+ : m_main_section_list(main_section_list),
+ m_dwo_section_list(dwo_section_list) {}
+
+ const DWARFDataExtractor &getOrLoadAbbrevData();
+ const DWARFDataExtractor &getOrLoadAddrData();
+ const DWARFDataExtractor &getOrLoadArangesData();
+ const DWARFDataExtractor &getOrLoadDebugInfoData();
+ const DWARFDataExtractor &getOrLoadLineData();
+ const DWARFDataExtractor &getOrLoadLineStrData();
+ const DWARFDataExtractor &getOrLoadMacroData();
+ const DWARFDataExtractor &getOrLoadRangesData();
+ const DWARFDataExtractor &getOrLoadRngListsData();
+ const DWARFDataExtractor &getOrLoadStrData();
+ const DWARFDataExtractor &getOrLoadStrOffsetsData();
+ const DWARFDataExtractor &getOrLoadDebugTypesData();
+
+ llvm::DWARFContext &GetAsLLVM();
+};
+} // namespace lldb_private
+
+#endif
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 22b70b2d6852..9d97ca15a252 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -1,16 +1,14 @@
//===-- DWARFDIE.cpp --------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DWARFDIE.h"
#include "DWARFASTParser.h"
-#include "DWARFDIECollection.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDeclContext.h"
@@ -18,20 +16,75 @@
using namespace lldb_private;
-void DWARFDIE::ElaboratingDIEIterator::Next() {
- assert(!m_worklist.empty() && "Incrementing end iterator?");
+namespace {
+
+/// Iterate through all DIEs elaborating (i.e. reachable by a chain of
+/// DW_AT_specification and DW_AT_abstract_origin attributes) a given DIE. For
+/// convenience, the starting die is included in the sequence as the first
+/// item.
+class ElaboratingDIEIterator
+ : public std::iterator<std::input_iterator_tag, DWARFDIE> {
+
+ // The operating invariant is: top of m_worklist contains the "current" item
+ // and the rest of the list are items yet to be visited. An empty worklist
+ // means we've reached the end.
+ // Infinite recursion is prevented by maintaining a list of seen DIEs.
+ // Container sizes are optimized for the case of following DW_AT_specification
+ // and DW_AT_abstract_origin just once.
+ llvm::SmallVector<DWARFDIE, 2> m_worklist;
+ llvm::SmallSet<lldb::user_id_t, 3> m_seen;
+
+ void Next() {
+ assert(!m_worklist.empty() && "Incrementing end iterator?");
+
+ // Pop the current item from the list.
+ DWARFDIE die = m_worklist.back();
+ m_worklist.pop_back();
+
+ // And add back any items that elaborate it.
+ for (dw_attr_t attr : {DW_AT_specification, DW_AT_abstract_origin}) {
+ if (DWARFDIE d = die.GetReferencedDIE(attr))
+ if (m_seen.insert(die.GetID()).second)
+ m_worklist.push_back(d);
+ }
+ }
- // Pop the current item from the list.
- DWARFDIE die = m_worklist.back();
- m_worklist.pop_back();
+public:
+ /// An iterator starting at die d.
+ explicit ElaboratingDIEIterator(DWARFDIE d) : m_worklist(1, d) {}
- // And add back any items that elaborate it.
- for (dw_attr_t attr : {DW_AT_specification, DW_AT_abstract_origin}) {
- if (DWARFDIE d = die.GetReferencedDIE(attr))
- if (m_seen.insert(die.GetID()).second)
- m_worklist.push_back(d);
+ /// End marker
+ ElaboratingDIEIterator() {}
+
+ const DWARFDIE &operator*() const { return m_worklist.back(); }
+ ElaboratingDIEIterator &operator++() {
+ Next();
+ return *this;
+ }
+ ElaboratingDIEIterator operator++(int) {
+ ElaboratingDIEIterator I = *this;
+ Next();
+ return I;
}
+
+ friend bool operator==(const ElaboratingDIEIterator &a,
+ const ElaboratingDIEIterator &b) {
+ if (a.m_worklist.empty() || b.m_worklist.empty())
+ return a.m_worklist.empty() == b.m_worklist.empty();
+ return a.m_worklist.back() == b.m_worklist.back();
+ }
+ friend bool operator!=(const ElaboratingDIEIterator &a,
+ const ElaboratingDIEIterator &b) {
+ return !(a == b);
+ }
+};
+
+llvm::iterator_range<ElaboratingDIEIterator>
+elaborating_dies(const DWARFDIE &die) {
+ return llvm::make_range(ElaboratingDIEIterator(die),
+ ElaboratingDIEIterator());
}
+} // namespace
DWARFDIE
DWARFDIE::GetParent() const {
@@ -59,12 +112,10 @@ DWARFDIE::GetSibling() const {
DWARFDIE
DWARFDIE::GetReferencedDIE(const dw_attr_t attr) const {
- const dw_offset_t die_offset =
- GetAttributeValueAsReference(attr, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET)
- return GetDIE(die_offset);
+ if (IsValid())
+ return m_die->GetAttributeValueAsReference(GetCU(), attr);
else
- return DWARFDIE();
+ return {};
}
DWARFDIE
@@ -79,12 +130,11 @@ DWARFDIE
DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const {
if (IsValid()) {
DWARFUnit *cu = GetCU();
- SymbolFileDWARF *dwarf = cu->GetSymbolFileDWARF();
const bool check_specification_or_abstract_origin = true;
DWARFFormValue form_value;
- if (m_die->GetAttributeValue(dwarf, cu, attr, form_value, nullptr,
+ if (m_die->GetAttributeValue(cu, attr, form_value, nullptr,
check_specification_or_abstract_origin))
- return dwarf->GetDIE(DIERef(form_value));
+ return form_value.Reference();
}
return DWARFDIE();
}
@@ -96,13 +146,14 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t file_addr) const {
DWARFUnit *cu = GetCU();
DWARFDebugInfoEntry *function_die = nullptr;
DWARFDebugInfoEntry *block_die = nullptr;
- if (m_die->LookupAddress(file_addr, dwarf, cu, &function_die, &block_die)) {
+ if (m_die->LookupAddress(file_addr, cu, &function_die, &block_die)) {
if (block_die && block_die != function_die) {
if (cu->ContainsDIEOffset(block_die->GetOffset()))
return DWARFDIE(cu, block_die);
else
- return DWARFDIE(dwarf->DebugInfo()->GetCompileUnit(
- DIERef(cu->GetOffset(), block_die->GetOffset())),
+ return DWARFDIE(dwarf->DebugInfo()->GetUnit(DIERef(
+ cu->GetSymbolFileDWARF().GetDwoNum(),
+ cu->GetDebugSection(), block_die->GetOffset())),
block_die);
}
}
@@ -112,25 +163,149 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t file_addr) const {
const char *DWARFDIE::GetMangledName() const {
if (IsValid())
- return m_die->GetMangledName(GetDWARF(), m_cu);
+ return m_die->GetMangledName(m_cu);
else
return nullptr;
}
const char *DWARFDIE::GetPubname() const {
if (IsValid())
- return m_die->GetPubname(GetDWARF(), m_cu);
+ return m_die->GetPubname(m_cu);
else
return nullptr;
}
const char *DWARFDIE::GetQualifiedName(std::string &storage) const {
if (IsValid())
- return m_die->GetQualifiedName(GetDWARF(), m_cu, storage);
+ return m_die->GetQualifiedName(m_cu, storage);
else
return nullptr;
}
+// GetName
+//
+// Get value of the DW_AT_name attribute and place that value into the supplied
+// stream object. If the DIE is a NULL object "NULL" is placed into the stream,
+// and if no DW_AT_name attribute exists for the DIE then nothing is printed.
+void DWARFDIE::GetName(Stream &s) const {
+ if (!IsValid())
+ return;
+ if (GetDIE()->IsNULL()) {
+ s.PutCString("NULL");
+ return;
+ }
+ const char *name = GetDIE()->GetAttributeValueAsString(GetCU(), DW_AT_name, nullptr, true);
+ if (!name)
+ return;
+ s.PutCString(name);
+}
+
+// AppendTypeName
+//
+// Follows the type name definition down through all needed tags to end up with
+// a fully qualified type name and dump the results to the supplied stream.
+// This is used to show the name of types given a type identifier.
+void DWARFDIE::AppendTypeName(Stream &s) const {
+ if (!IsValid())
+ return;
+ if (GetDIE()->IsNULL()) {
+ s.PutCString("NULL");
+ return;
+ }
+ if (const char *name = GetPubname()) {
+ s.PutCString(name);
+ return;
+ }
+ switch (Tag()) {
+ case DW_TAG_array_type:
+ break; // print out a "[]" after printing the full type of the element
+ // below
+ case DW_TAG_base_type:
+ s.PutCString("base ");
+ break;
+ case DW_TAG_class_type:
+ s.PutCString("class ");
+ break;
+ case DW_TAG_const_type:
+ s.PutCString("const ");
+ break;
+ case DW_TAG_enumeration_type:
+ s.PutCString("enum ");
+ break;
+ case DW_TAG_file_type:
+ s.PutCString("file ");
+ break;
+ case DW_TAG_interface_type:
+ s.PutCString("interface ");
+ break;
+ case DW_TAG_packed_type:
+ s.PutCString("packed ");
+ break;
+ case DW_TAG_pointer_type:
+ break; // print out a '*' after printing the full type below
+ case DW_TAG_ptr_to_member_type:
+ break; // print out a '*' after printing the full type below
+ case DW_TAG_reference_type:
+ break; // print out a '&' after printing the full type below
+ case DW_TAG_restrict_type:
+ s.PutCString("restrict ");
+ break;
+ case DW_TAG_set_type:
+ s.PutCString("set ");
+ break;
+ case DW_TAG_shared_type:
+ s.PutCString("shared ");
+ break;
+ case DW_TAG_string_type:
+ s.PutCString("string ");
+ break;
+ case DW_TAG_structure_type:
+ s.PutCString("struct ");
+ break;
+ case DW_TAG_subrange_type:
+ s.PutCString("subrange ");
+ break;
+ case DW_TAG_subroutine_type:
+ s.PutCString("function ");
+ break;
+ case DW_TAG_thrown_type:
+ s.PutCString("thrown ");
+ break;
+ case DW_TAG_union_type:
+ s.PutCString("union ");
+ break;
+ case DW_TAG_unspecified_type:
+ s.PutCString("unspecified ");
+ break;
+ case DW_TAG_volatile_type:
+ s.PutCString("volatile ");
+ break;
+ default:
+ return;
+ }
+
+ // Follow the DW_AT_type if possible
+ if (DWARFDIE next_die = GetAttributeValueAsReferenceDIE(DW_AT_type))
+ next_die.AppendTypeName(s);
+
+ switch (Tag()) {
+ case DW_TAG_array_type:
+ s.PutCString("[]");
+ break;
+ case DW_TAG_pointer_type:
+ s.PutChar('*');
+ break;
+ case DW_TAG_ptr_to_member_type:
+ s.PutChar('*');
+ break;
+ case DW_TAG_reference_type:
+ s.PutChar('&');
+ break;
+ default:
+ break;
+ }
+}
+
lldb_private::Type *DWARFDIE::ResolveType() const {
if (IsValid())
return GetDWARF()->ResolveType(*this, true);
@@ -138,29 +313,30 @@ lldb_private::Type *DWARFDIE::ResolveType() const {
return nullptr;
}
-lldb_private::Type *DWARFDIE::ResolveTypeUID(const DIERef &die_ref) const {
- SymbolFileDWARF *dwarf = GetDWARF();
- if (dwarf)
- return dwarf->ResolveTypeUID(dwarf->GetDIE(die_ref), true);
- else
- return nullptr;
+lldb_private::Type *DWARFDIE::ResolveTypeUID(const DWARFDIE &die) const {
+ if (SymbolFileDWARF *dwarf = GetDWARF())
+ return dwarf->ResolveTypeUID(die, true);
+ return nullptr;
}
-void DWARFDIE::GetDeclContextDIEs(DWARFDIECollection &decl_context_dies) const {
- if (IsValid()) {
- DWARFDIE parent_decl_ctx_die =
- m_die->GetParentDeclContextDIE(GetDWARF(), GetCU());
- if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != GetDIE()) {
- decl_context_dies.Append(parent_decl_ctx_die);
- parent_decl_ctx_die.GetDeclContextDIEs(decl_context_dies);
- }
+std::vector<DWARFDIE> DWARFDIE::GetDeclContextDIEs() const {
+ if (!IsValid())
+ return {};
+
+ std::vector<DWARFDIE> result;
+ DWARFDIE parent = GetParentDeclContextDIE();
+ while (parent.IsValid() && parent.GetDIE() != GetDIE()) {
+ result.push_back(std::move(parent));
+ parent = parent.GetParentDeclContextDIE();
}
+
+ return result;
}
void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const {
if (IsValid()) {
dwarf_decl_ctx.SetLanguage(GetLanguage());
- m_die->GetDWARFDeclContext(GetDWARF(), GetCU(), dwarf_decl_ctx);
+ m_die->GetDWARFDeclContext(GetCU(), dwarf_decl_ctx);
} else {
dwarf_decl_ctx.Clear();
}
@@ -218,7 +394,7 @@ void DWARFDIE::GetDeclContext(std::vector<CompilerContext> &context) const {
DWARFDIE
DWARFDIE::GetParentDeclContextDIE() const {
if (IsValid())
- return m_die->GetParentDeclContextDIE(GetDWARF(), m_cu);
+ return m_die->GetParentDeclContextDIE(m_cu);
else
return DWARFDIE();
}
@@ -230,7 +406,7 @@ bool DWARFDIE::IsStructUnionOrClass() const {
}
bool DWARFDIE::IsMethod() const {
- for (DWARFDIE d: elaborating_dies())
+ for (DWARFDIE d : elaborating_dies(*this))
if (d.GetParent().IsStructUnionOrClass())
return true;
return false;
@@ -276,8 +452,8 @@ bool DWARFDIE::GetDIENamesAndRanges(
lldb_private::DWARFExpression *frame_base) const {
if (IsValid()) {
return m_die->GetDIENamesAndRanges(
- GetDWARF(), GetCU(), name, mangled, ranges, decl_file, decl_line,
- decl_column, call_file, call_line, call_column, frame_base);
+ GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column,
+ call_file, call_line, call_column, frame_base);
} else
return false;
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index b0d06a886ac1..7753ec9008cb 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -1,9 +1,8 @@
//===-- DWARFDIE.h ----------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -15,46 +14,37 @@
class DWARFDIE : public DWARFBaseDIE {
public:
- class ElaboratingDIEIterator;
-
using DWARFBaseDIE::DWARFBaseDIE;
- //----------------------------------------------------------------------
// Tests
- //----------------------------------------------------------------------
bool IsStructUnionOrClass() const;
bool IsMethod() const;
- //----------------------------------------------------------------------
// Accessors
- //----------------------------------------------------------------------
lldb::ModuleSP GetContainingDWOModule() const;
DWARFDIE
GetContainingDWOModuleDIE() const;
- inline llvm::iterator_range<ElaboratingDIEIterator> elaborating_dies() const;
-
- //----------------------------------------------------------------------
// Accessing information about a DIE
- //----------------------------------------------------------------------
const char *GetMangledName() const;
const char *GetPubname() const;
const char *GetQualifiedName(std::string &storage) const;
+ using DWARFBaseDIE::GetName;
+ void GetName(lldb_private::Stream &s) const;
+
+ void AppendTypeName(lldb_private::Stream &s) const;
+
lldb_private::Type *ResolveType() const;
- //----------------------------------------------------------------------
// Resolve a type by UID using this DIE's DWARF file
- //----------------------------------------------------------------------
- lldb_private::Type *ResolveTypeUID(const DIERef &die_ref) const;
+ lldb_private::Type *ResolveTypeUID(const DWARFDIE &die) const;
- //----------------------------------------------------------------------
// Functions for obtaining DIE relations and references
- //----------------------------------------------------------------------
DWARFDIE
GetParent() const;
@@ -68,11 +58,9 @@ public:
DWARFDIE
GetReferencedDIE(const dw_attr_t attr) const;
- //----------------------------------------------------------------------
// Get a another DIE from the same DWARF file as this DIE. This will
// check the current DIE's compile unit first to see if "die_offset" is
// in the same compile unit, and fall back to checking the DWARF file.
- //----------------------------------------------------------------------
DWARFDIE
GetDIE(dw_offset_t die_offset) const;
using DWARFBaseDIE::GetDIE;
@@ -83,10 +71,8 @@ public:
DWARFDIE
GetParentDeclContextDIE() const;
- //----------------------------------------------------------------------
// DeclContext related functions
- //----------------------------------------------------------------------
- void GetDeclContextDIEs(DWARFDIECollection &decl_context_dies) const;
+ std::vector<DWARFDIE> GetDeclContextDIEs() const;
void GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const;
@@ -95,13 +81,11 @@ public:
void
GetDeclContext(std::vector<lldb_private::CompilerContext> &context) const;
- //----------------------------------------------------------------------
// Getting attribute values from the DIE.
//
// GetAttributeValueAsXXX() functions should only be used if you are
// looking for one or two attributes on a DIE. If you are trying to
// parse all attributes, use GetAttributes (...) instead
- //----------------------------------------------------------------------
DWARFDIE
GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;
@@ -111,9 +95,7 @@ public:
int &call_line, int &call_column,
lldb_private::DWARFExpression *frame_base) const;
- //----------------------------------------------------------------------
// CompilerDecl related functions
- //----------------------------------------------------------------------
lldb_private::CompilerDecl GetDecl() const;
@@ -122,58 +104,4 @@ public:
lldb_private::CompilerDeclContext GetContainingDeclContext() const;
};
-/// Iterate through all DIEs elaborating (i.e. reachable by a chain of
-/// DW_AT_specification and DW_AT_abstract_origin attributes) a given DIE. For
-/// convenience, the starting die is included in the sequence as the first
-/// item.
-class DWARFDIE::ElaboratingDIEIterator
- : public std::iterator<std::input_iterator_tag, DWARFDIE> {
-
- // The operating invariant is: top of m_worklist contains the "current" item
- // and the rest of the list are items yet to be visited. An empty worklist
- // means we've reached the end.
- // Infinite recursion is prevented by maintaining a list of seen DIEs.
- // Container sizes are optimized for the case of following DW_AT_specification
- // and DW_AT_abstract_origin just once.
- llvm::SmallVector<DWARFDIE, 2> m_worklist;
- llvm::SmallSet<lldb::user_id_t, 3> m_seen;
-
- void Next();
-
-public:
- /// An iterator starting at die d.
- explicit ElaboratingDIEIterator(DWARFDIE d) : m_worklist(1, d) {}
-
- /// End marker
- ElaboratingDIEIterator() {}
-
- const DWARFDIE &operator*() const { return m_worklist.back(); }
- ElaboratingDIEIterator &operator++() {
- Next();
- return *this;
- }
- ElaboratingDIEIterator operator++(int) {
- ElaboratingDIEIterator I = *this;
- Next();
- return I;
- }
-
- friend bool operator==(const ElaboratingDIEIterator &a,
- const ElaboratingDIEIterator &b) {
- if (a.m_worklist.empty() || b.m_worklist.empty())
- return a.m_worklist.empty() == b.m_worklist.empty();
- return a.m_worklist.back() == b.m_worklist.back();
- }
- friend bool operator!=(const ElaboratingDIEIterator &a,
- const ElaboratingDIEIterator &b) {
- return !(a == b);
- }
-};
-
-llvm::iterator_range<DWARFDIE::ElaboratingDIEIterator>
-DWARFDIE::elaborating_dies() const {
- return llvm::make_range(ElaboratingDIEIterator(*this),
- ElaboratingDIEIterator());
-}
-
#endif // SymbolFileDWARF_DWARFDIE_h_
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
deleted file mode 100644
index 1e5bf619f798..000000000000
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-//===-- DWARFDIECollection.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DWARFDIECollection.h"
-
-#include <algorithm>
-
-#include "lldb/Utility/Stream.h"
-
-using namespace lldb_private;
-using namespace std;
-
-void DWARFDIECollection::Append(const DWARFDIE &die) { m_dies.push_back(die); }
-
-DWARFDIE
-DWARFDIECollection::GetDIEAtIndex(uint32_t idx) const {
- if (idx < m_dies.size())
- return m_dies[idx];
- return DWARFDIE();
-}
-
-size_t DWARFDIECollection::Size() const { return m_dies.size(); }
-
-void DWARFDIECollection::Dump(Stream *s, const char *title) const {
- if (title && title[0] != '\0')
- s->Printf("%s\n", title);
- for (const auto &die : m_dies)
- s->Printf("0x%8.8x\n", die.GetOffset());
-}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
deleted file mode 100644
index e1e73e71ae7f..000000000000
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===-- DWARFDIECollection.h ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SymbolFileDWARF_DWARFDIECollection_h_
-#define SymbolFileDWARF_DWARFDIECollection_h_
-
-#include "DWARFDIE.h"
-#include <vector>
-
-class DWARFDIECollection {
-public:
- DWARFDIECollection() : m_dies() {}
- ~DWARFDIECollection() {}
-
- void Append(const DWARFDIE &die);
-
- void Dump(lldb_private::Stream *s, const char *title) const;
-
- DWARFDIE
- GetDIEAtIndex(uint32_t idx) const;
-
- size_t Size() const;
-
-protected:
- typedef std::vector<DWARFDIE> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- collection m_dies; // Ordered list of die offsets
-};
-
-#endif // SymbolFileDWARF_DWARFDIECollection_h_
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
index 2fcdd34d532f..1678b228137f 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
@@ -1,27 +1,30 @@
//===-- DWARFDataExtractor.cpp ----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DWARFDataExtractor.h"
+#include "llvm/ADT/StringRef.h"
namespace lldb_private {
uint64_t
DWARFDataExtractor::GetDWARFInitialLength(lldb::offset_t *offset_ptr) const {
- uint64_t length = GetU32(offset_ptr);
- m_is_dwarf64 = (length == UINT32_MAX);
- if (m_is_dwarf64)
- length = GetU64(offset_ptr);
- return length;
+ return GetU32(offset_ptr);
}
dw_offset_t
DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const {
return GetMaxU64(offset_ptr, GetDWARFSizeOfOffset());
}
+
+llvm::DWARFDataExtractor DWARFDataExtractor::GetAsLLVM() const {
+ return llvm::DWARFDataExtractor(
+ llvm::StringRef(reinterpret_cast<const char *>(GetDataStart()),
+ GetByteSize()),
+ GetByteOrder() == lldb::eByteOrderLittle, GetAddressByteSize());
}
+} // namespace lldb_private
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
index 1f342035f135..22db5e8c0b79 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
@@ -1,9 +1,8 @@
//===-- DWARFDataExtractor.h ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -12,27 +11,26 @@
#include "lldb/Core/dwarf.h"
#include "lldb/Utility/DataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
namespace lldb_private {
class DWARFDataExtractor : public DataExtractor {
public:
- DWARFDataExtractor() : DataExtractor(), m_is_dwarf64(false) {}
+ DWARFDataExtractor() = default;
DWARFDataExtractor(const DWARFDataExtractor &data, lldb::offset_t offset,
lldb::offset_t length)
- : DataExtractor(data, offset, length), m_is_dwarf64(false) {}
+ : DataExtractor(data, offset, length) {}
uint64_t GetDWARFInitialLength(lldb::offset_t *offset_ptr) const;
dw_offset_t GetDWARFOffset(lldb::offset_t *offset_ptr) const;
- size_t GetDWARFSizeofInitialLength() const { return m_is_dwarf64 ? 12 : 4; }
- size_t GetDWARFSizeOfOffset() const { return m_is_dwarf64 ? 8 : 4; }
- bool IsDWARF64() const { return m_is_dwarf64; }
+ size_t GetDWARFSizeofInitialLength() const { return 4; }
+ size_t GetDWARFSizeOfOffset() const { return 4; }
-protected:
- mutable bool m_is_dwarf64;
+ llvm::DWARFDataExtractor GetAsLLVM() const;
};
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
index affe4b85bdab..26301566a8e1 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
@@ -1,9 +1,8 @@
//===-- DWARFDebugAbbrev.cpp ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -15,50 +14,41 @@ using namespace lldb;
using namespace lldb_private;
using namespace std;
-//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::Clear()
-//----------------------------------------------------------------------
void DWARFAbbreviationDeclarationSet::Clear() {
m_idx_offset = 0;
m_decls.clear();
}
-//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::Extract()
-//----------------------------------------------------------------------
-bool DWARFAbbreviationDeclarationSet::Extract(const DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr) {
+llvm::Error
+DWARFAbbreviationDeclarationSet::extract(const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr) {
const lldb::offset_t begin_offset = *offset_ptr;
m_offset = begin_offset;
Clear();
DWARFAbbreviationDeclaration abbrevDeclaration;
dw_uleb128_t prev_abbr_code = 0;
- while (abbrevDeclaration.Extract(data, offset_ptr)) {
+ while (true) {
+ llvm::Expected<DWARFEnumState> es =
+ abbrevDeclaration.extract(data, offset_ptr);
+ if (!es)
+ return es.takeError();
+ if (*es == DWARFEnumState::Complete)
+ break;
m_decls.push_back(abbrevDeclaration);
if (m_idx_offset == 0)
m_idx_offset = abbrevDeclaration.Code();
- else {
- if (prev_abbr_code + 1 != abbrevDeclaration.Code())
- m_idx_offset =
- UINT32_MAX; // Out of order indexes, we can't do O(1) lookups...
+ else if (prev_abbr_code + 1 != abbrevDeclaration.Code()) {
+ // Out of order indexes, we can't do O(1) lookups...
+ m_idx_offset = UINT32_MAX;
}
prev_abbr_code = abbrevDeclaration.Code();
}
- return begin_offset != *offset_ptr;
+ return llvm::ErrorSuccess();
}
-//----------------------------------------------------------------------
-// DWARFAbbreviationDeclarationSet::Dump()
-//----------------------------------------------------------------------
-void DWARFAbbreviationDeclarationSet::Dump(Stream *s) const {
- std::for_each(
- m_decls.begin(), m_decls.end(),
- bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump), s));
-}
-
-//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration()
-//----------------------------------------------------------------------
const DWARFAbbreviationDeclaration *
DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(
dw_uleb128_t abbrCode) const {
@@ -74,32 +64,11 @@ DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(
if (idx < m_decls.size())
return &m_decls[idx];
}
- return NULL;
+ return nullptr;
}
-//----------------------------------------------------------------------
-// DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential()
-//
-// Append an abbreviation declaration with a sequential code for O(n) lookups.
-// Handy when creating an DWARFAbbreviationDeclarationSet.
-//----------------------------------------------------------------------
-dw_uleb128_t DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(
- const DWARFAbbreviationDeclaration &abbrevDecl) {
- // Get the next abbreviation code based on our current array size
- dw_uleb128_t code = m_decls.size() + 1;
-
- // Push the new declaration on the back
- m_decls.push_back(abbrevDecl);
-
- // Update the code for this new declaration
- m_decls.back().SetCode(code);
-
- return code; // return the new abbreviation code!
-}
-//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::GetUnsupportedForms()
-//----------------------------------------------------------------------
void DWARFAbbreviationDeclarationSet::GetUnsupportedForms(
std::set<dw_form_t> &invalid_forms) const {
for (const auto &abbr_decl : m_decls) {
@@ -112,13 +81,11 @@ void DWARFAbbreviationDeclarationSet::GetUnsupportedForms(
}
}
-//----------------------------------------------------------------------
// Encode
//
// Encode the abbreviation table onto the end of the buffer provided into a
// byte representation as would be found in a ".debug_abbrev" debug information
// section.
-//----------------------------------------------------------------------
// void
// DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf)
// const
@@ -130,49 +97,29 @@ void DWARFAbbreviationDeclarationSet::GetUnsupportedForms(
// debug_abbrev_buf.Append8(0);
//}
-//----------------------------------------------------------------------
// DWARFDebugAbbrev constructor
-//----------------------------------------------------------------------
DWARFDebugAbbrev::DWARFDebugAbbrev()
: m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {}
-//----------------------------------------------------------------------
// DWARFDebugAbbrev::Parse()
-//----------------------------------------------------------------------
-void DWARFDebugAbbrev::Parse(const DWARFDataExtractor &data) {
+llvm::Error DWARFDebugAbbrev::parse(const DWARFDataExtractor &data) {
lldb::offset_t offset = 0;
while (data.ValidOffset(offset)) {
uint32_t initial_cu_offset = offset;
DWARFAbbreviationDeclarationSet abbrevDeclSet;
- if (abbrevDeclSet.Extract(data, &offset))
- m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
- else
- break;
- }
- m_prev_abbr_offset_pos = m_abbrevCollMap.end();
-}
+ llvm::Error error = abbrevDeclSet.extract(data, &offset);
+ if (error)
+ return error;
-//----------------------------------------------------------------------
-// DWARFDebugAbbrev::Dump()
-//----------------------------------------------------------------------
-void DWARFDebugAbbrev::Dump(Stream *s) const {
- if (m_abbrevCollMap.empty()) {
- s->PutCString("< EMPTY >\n");
- return;
- }
-
- DWARFAbbreviationDeclarationCollMapConstIter pos;
- for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos) {
- s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first);
- pos->second.Dump(s);
+ m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
}
+ m_prev_abbr_offset_pos = m_abbrevCollMap.end();
+ return llvm::ErrorSuccess();
}
-//----------------------------------------------------------------------
// DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
-//----------------------------------------------------------------------
const DWARFAbbreviationDeclarationSet *
DWARFDebugAbbrev::GetAbbreviationDeclarationSet(
dw_offset_t cu_abbr_offset) const {
@@ -188,12 +135,10 @@ DWARFDebugAbbrev::GetAbbreviationDeclarationSet(
if (pos != m_abbrevCollMap.end())
return &(pos->second);
- return NULL;
+ return nullptr;
}
-//----------------------------------------------------------------------
// DWARFDebugAbbrev::GetUnsupportedForms()
-//----------------------------------------------------------------------
void DWARFDebugAbbrev::GetUnsupportedForms(
std::set<dw_form_t> &invalid_forms) const {
for (const auto &pair : m_abbrevCollMap)
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
index 2bacb6349b6f..9c4729326081 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
@@ -1,9 +1,8 @@
//===-- DWARFDebugAbbrev.h --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -35,17 +34,21 @@ public:
void Clear();
dw_offset_t GetOffset() const { return m_offset; }
- void Dump(lldb_private::Stream *s) const;
- bool Extract(const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr);
+
+ /// Extract all abbrev decls in a set. Returns llvm::ErrorSuccess() on
+ /// success, and an appropriate llvm::Error object otherwise.
+ llvm::Error extract(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
// void Encode(BinaryStreamBuf& debug_abbrev_buf) const;
- dw_uleb128_t
- AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration &abbrevDecl);
void GetUnsupportedForms(std::set<dw_form_t> &invalid_forms) const;
const DWARFAbbreviationDeclaration *
GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const;
+ /// Unit test accessor functions.
+ /// @{
+ uint32_t GetIndexOffset() const { return m_idx_offset; }
+ /// @}
private:
dw_offset_t m_offset;
uint32_t m_idx_offset;
@@ -64,8 +67,10 @@ public:
DWARFDebugAbbrev();
const DWARFAbbreviationDeclarationSet *
GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const;
- void Dump(lldb_private::Stream *s) const;
- void Parse(const lldb_private::DWARFDataExtractor &data);
+ /// Extract all abbreviations for a particular compile unit. Returns
+ /// llvm::ErrorSuccess() on success, and an appropriate llvm::Error object
+ /// otherwise.
+ llvm::Error parse(const lldb_private::DWARFDataExtractor &data);
void GetUnsupportedForms(std::set<dw_form_t> &invalid_forms) const;
protected:
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
index 00265361f865..86ce3b329b25 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
@@ -1,17 +1,15 @@
//===-- DWARFDebugArangeSet.cpp ---------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DWARFDebugArangeSet.h"
-
-#include "SymbolFileDWARF.h"
-#include "lldb/Utility/Stream.h"
-#include <assert.h>
+#include "DWARFDataExtractor.h"
+#include "llvm/Object/Error.h"
+#include <cassert>
using namespace lldb_private;
@@ -34,213 +32,88 @@ void DWARFDebugArangeSet::Clear() {
m_arange_descriptors.clear();
}
-void DWARFDebugArangeSet::SetHeader(uint16_t version, uint32_t cu_offset,
- uint8_t addr_size, uint8_t seg_size) {
- m_header.version = version;
- m_header.cu_offset = cu_offset;
- m_header.addr_size = addr_size;
- m_header.seg_size = seg_size;
-}
-
-void DWARFDebugArangeSet::Compact() {
- if (m_arange_descriptors.empty())
- return;
-
- // Iterate through all arange descriptors and combine any ranges that overlap
- // or have matching boundaries. The m_arange_descriptors are assumed to be in
- // ascending order after being built by adding descriptors using the
- // AddDescriptor method.
- uint32_t i = 0;
- while (i + 1 < m_arange_descriptors.size()) {
- if (m_arange_descriptors[i].end_address() >=
- m_arange_descriptors[i + 1].address) {
- // The current range ends at or exceeds the start of the next address
- // range. Compute the max end address between the two and use that to
- // make the new length.
- const dw_addr_t max_end_addr =
- std::max(m_arange_descriptors[i].end_address(),
- m_arange_descriptors[i + 1].end_address());
- m_arange_descriptors[i].length =
- max_end_addr - m_arange_descriptors[i].address;
- // Now remove the next entry as it was just combined with the previous
- // one.
- m_arange_descriptors.erase(m_arange_descriptors.begin() + i + 1);
- } else {
- // Discontiguous address range, just proceed to the next one.
- ++i;
- }
- }
-}
-//----------------------------------------------------------------------
-// Compare function DWARFDebugArangeSet::Descriptor structures
-//----------------------------------------------------------------------
-static bool DescriptorLessThan(const DWARFDebugArangeSet::Descriptor &range1,
- const DWARFDebugArangeSet::Descriptor &range2) {
- return range1.address < range2.address;
-}
-
-//----------------------------------------------------------------------
-// Add a range descriptor and keep things sorted so we can easily compact the
-// ranges before being saved or used.
-//----------------------------------------------------------------------
-void DWARFDebugArangeSet::AddDescriptor(
- const DWARFDebugArangeSet::Descriptor &range) {
- if (m_arange_descriptors.empty()) {
- m_arange_descriptors.push_back(range);
- return;
- }
-
- DescriptorIter end = m_arange_descriptors.end();
- DescriptorIter pos =
- lower_bound(m_arange_descriptors.begin(), end, range, DescriptorLessThan);
- const dw_addr_t range_end_addr = range.end_address();
- if (pos != end) {
- const dw_addr_t found_end_addr = pos->end_address();
- if (range.address < pos->address) {
- if (range_end_addr < pos->address) {
- // Non-contiguous entries, add this one before the found entry
- m_arange_descriptors.insert(pos, range);
- } else if (range_end_addr == pos->address) {
- // The top end of 'range' is the lower end of the entry pointed to by
- // 'pos'. We can combine range with the entry we found by setting the
- // starting address and increasing the length since they don't overlap.
- pos->address = range.address;
- pos->length += range.length;
- } else {
- // We can combine these two and make sure the largest end address is
- // used to make end address.
- pos->address = range.address;
- pos->length = std::max(found_end_addr, range_end_addr) - pos->address;
- }
- } else if (range.address == pos->address) {
- pos->length = std::max(pos->length, range.length);
- }
- } else {
- // NOTE: 'pos' points to entry past the end which is ok for insert,
- // don't use otherwise!!!
- const dw_addr_t max_addr = m_arange_descriptors.back().end_address();
- if (max_addr < range.address) {
- // Non-contiguous entries, add this one before the found entry
- m_arange_descriptors.insert(pos, range);
- } else if (max_addr == range.address) {
- m_arange_descriptors.back().length += range.length;
- } else {
- m_arange_descriptors.back().length = std::max(max_addr, range_end_addr) -
- m_arange_descriptors.back().address;
- }
- }
-}
-
-bool DWARFDebugArangeSet::Extract(const DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr) {
- if (data.ValidOffset(*offset_ptr)) {
- m_arange_descriptors.clear();
- m_offset = *offset_ptr;
+llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ assert(data.ValidOffset(*offset_ptr));
- // 7.20 Address Range Table
- //
- // Each set of entries in the table of address ranges contained in the
- // .debug_aranges section begins with a header consisting of: a 4-byte
- // length containing the length of the set of entries for this compilation
- // unit, not including the length field itself; a 2-byte version identifier
- // containing the value 2 for DWARF Version 2; a 4-byte offset into
- // the.debug_infosection; a 1-byte unsigned integer containing the size in
- // bytes of an address (or the offset portion of an address for segmented
- // addressing) on the target system; and a 1-byte unsigned integer
- // containing the size in bytes of a segment descriptor on the target
- // system. This header is followed by a series of tuples. Each tuple
- // consists of an address and a length, each in the size appropriate for an
- // address on the target architecture.
- m_header.length = data.GetDWARFInitialLength(offset_ptr);
- m_header.version = data.GetU16(offset_ptr);
- m_header.cu_offset = data.GetDWARFOffset(offset_ptr);
- m_header.addr_size = data.GetU8(offset_ptr);
- m_header.seg_size = data.GetU8(offset_ptr);
-
- // Try to avoid reading invalid arange sets by making sure:
- // 1 - the version looks good
- // 2 - the address byte size looks plausible
- // 3 - the length seems to make sense
- // size looks plausible
- if ((m_header.version >= 2 && m_header.version <= 5) &&
- (m_header.addr_size == 4 || m_header.addr_size == 8) &&
- (m_header.length > 0)) {
- if (data.ValidOffset(m_offset + sizeof(m_header.length) +
- m_header.length - 1)) {
- // The first tuple following the header in each set begins at an offset
- // that is a multiple of the size of a single tuple (that is, twice the
- // size of an address). The header is padded, if necessary, to the
- // appropriate boundary.
- const uint32_t header_size = *offset_ptr - m_offset;
- const uint32_t tuple_size = m_header.addr_size << 1;
- uint32_t first_tuple_offset = 0;
- while (first_tuple_offset < header_size)
- first_tuple_offset += tuple_size;
-
- *offset_ptr = m_offset + first_tuple_offset;
-
- Descriptor arangeDescriptor;
-
- static_assert(
- sizeof(arangeDescriptor.address) == sizeof(arangeDescriptor.length),
- "DWARFDebugArangeSet::Descriptor.address and "
- "DWARFDebugArangeSet::Descriptor.length must have same size");
-
- while (data.ValidOffset(*offset_ptr)) {
- arangeDescriptor.address =
- data.GetMaxU64(offset_ptr, m_header.addr_size);
- arangeDescriptor.length =
- data.GetMaxU64(offset_ptr, m_header.addr_size);
-
- // Each set of tuples is terminated by a 0 for the address and 0 for
- // the length.
- if (arangeDescriptor.address || arangeDescriptor.length)
- m_arange_descriptors.push_back(arangeDescriptor);
- else
- break; // We are done if we get a zero address and length
- }
- }
-#if defined(LLDB_CONFIGURATION_DEBUG)
- else {
- printf("warning: .debug_arange set length is too large arange data at "
- "0x%8.8x: length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, "
- "addr_size=%u, seg_size=%u\n",
- m_offset, m_header.length, m_header.version, m_header.cu_offset,
- m_header.addr_size, m_header.seg_size);
- }
-#endif
- }
-#if defined(LLDB_CONFIGURATION_DEBUG)
- else {
- printf("warning: .debug_arange set has bad header at 0x%8.8x: "
- "length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, "
- "addr_size=%u, seg_size=%u\n",
- m_offset, m_header.length, m_header.version, m_header.cu_offset,
- m_header.addr_size, m_header.seg_size);
- }
-#endif
-
- return !m_arange_descriptors.empty();
+ m_arange_descriptors.clear();
+ m_offset = *offset_ptr;
+
+ // 7.20 Address Range Table
+ //
+ // Each set of entries in the table of address ranges contained in the
+ // .debug_aranges section begins with a header consisting of: a 4-byte
+ // length containing the length of the set of entries for this compilation
+ // unit, not including the length field itself; a 2-byte version identifier
+ // containing the value 2 for DWARF Version 2; a 4-byte offset into
+ // the.debug_infosection; a 1-byte unsigned integer containing the size in
+ // bytes of an address (or the offset portion of an address for segmented
+ // addressing) on the target system; and a 1-byte unsigned integer
+ // containing the size in bytes of a segment descriptor on the target
+ // system. This header is followed by a series of tuples. Each tuple
+ // consists of an address and a length, each in the size appropriate for an
+ // address on the target architecture.
+ m_header.length = data.GetDWARFInitialLength(offset_ptr);
+ m_header.version = data.GetU16(offset_ptr);
+ m_header.cu_offset = data.GetDWARFOffset(offset_ptr);
+ m_header.addr_size = data.GetU8(offset_ptr);
+ m_header.seg_size = data.GetU8(offset_ptr);
+
+ // Try to avoid reading invalid arange sets by making sure:
+ // 1 - the version looks good
+ // 2 - the address byte size looks plausible
+ // 3 - the length seems to make sense
+ // size looks plausible
+ if (m_header.version < 2 || m_header.version > 5)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "Invalid arange header version");
+
+ if (m_header.addr_size != 4 && m_header.addr_size != 8)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "Invalid arange header address size");
+
+ if (m_header.length == 0)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "Invalid arange header length");
+
+ if (!data.ValidOffset(m_offset + sizeof(m_header.length) + m_header.length -
+ 1))
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "Invalid arange header length");
+
+ // The first tuple following the header in each set begins at an offset
+ // that is a multiple of the size of a single tuple (that is, twice the
+ // size of an address). The header is padded, if necessary, to the
+ // appropriate boundary.
+ const uint32_t header_size = *offset_ptr - m_offset;
+ const uint32_t tuple_size = m_header.addr_size << 1;
+ uint32_t first_tuple_offset = 0;
+ while (first_tuple_offset < header_size)
+ first_tuple_offset += tuple_size;
+
+ *offset_ptr = m_offset + first_tuple_offset;
+
+ Descriptor arangeDescriptor;
+
+ static_assert(sizeof(arangeDescriptor.address) ==
+ sizeof(arangeDescriptor.length),
+ "DWARFDebugArangeSet::Descriptor.address and "
+ "DWARFDebugArangeSet::Descriptor.length must have same size");
+
+ while (data.ValidOffset(*offset_ptr)) {
+ arangeDescriptor.address = data.GetMaxU64(offset_ptr, m_header.addr_size);
+ arangeDescriptor.length = data.GetMaxU64(offset_ptr, m_header.addr_size);
+
+ // Each set of tuples is terminated by a 0 for the address and 0 for
+ // the length.
+ if (!arangeDescriptor.address && !arangeDescriptor.length)
+ return llvm::ErrorSuccess();
+
+ m_arange_descriptors.push_back(arangeDescriptor);
}
- return false;
-}
-
-dw_offset_t DWARFDebugArangeSet::GetOffsetOfNextEntry() const {
- return m_offset + m_header.length + 4;
-}
-
-void DWARFDebugArangeSet::Dump(Stream *s) const {
- s->Printf("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, "
- "cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n",
- m_header.length, m_header.version, m_header.cu_offset,
- m_header.addr_size, m_header.seg_size);
- const uint32_t hex_width = m_header.addr_size * 2;
- DescriptorConstIter pos;
- DescriptorConstIter end = m_arange_descriptors.end();
- for (pos = m_arange_descriptors.begin(); pos != end; ++pos)
- s->Printf("[0x%*.*" PRIx64 " - 0x%*.*" PRIx64 ")\n", hex_width, hex_width,
- pos->address, hex_width, hex_width, pos->end_address());
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "arange descriptors not terminated by null entry");
}
class DescriptorContainsAddress {
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
index ae6319a13d0e..db0cf22a3f45 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
@@ -1,20 +1,18 @@
//===-- DWARFDebugArangeSet.h -----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef SymbolFileDWARF_DWARFDebugArangeSet_h_
#define SymbolFileDWARF_DWARFDebugArangeSet_h_
-#include "SymbolFileDWARF.h"
+#include "lldb/Core/dwarf.h"
+#include <cstdint>
#include <vector>
-class SymbolFileDWARF;
-
class DWARFDebugArangeSet {
public:
struct Header {
@@ -41,23 +39,11 @@ public:
DWARFDebugArangeSet();
void Clear();
void SetOffset(uint32_t offset) { m_offset = offset; }
- void SetHeader(uint16_t version, uint32_t cu_offset, uint8_t addr_size,
- uint8_t seg_size);
- void AddDescriptor(const DWARFDebugArangeSet::Descriptor &range);
- void Compact();
- bool Extract(const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr);
- void Dump(lldb_private::Stream *s) const;
- dw_offset_t GetCompileUnitDIEOffset() const { return m_header.cu_offset; }
- dw_offset_t GetOffsetOfNextEntry() const;
+ llvm::Error extract(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
dw_offset_t FindAddress(dw_addr_t address) const;
size_t NumDescriptors() const { return m_arange_descriptors.size(); }
const Header &GetHeader() const { return m_header; }
- const Descriptor *GetDescriptor(uint32_t i) const {
- if (i < m_arange_descriptors.size())
- return &m_arange_descriptors[i];
- return NULL;
- }
const Descriptor &GetDescriptorRef(uint32_t i) const {
return m_arange_descriptors[i];
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
index 02f528d571b0..ccf33e6dc341 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -1,39 +1,24 @@
//===-- DWARFDebugAranges.cpp -----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DWARFDebugAranges.h"
-
-#include <assert.h>
-#include <stdio.h>
-
-#include <algorithm>
-
+#include "DWARFDebugArangeSet.h"
+#include "DWARFUnit.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
-#include "DWARFUnit.h"
-#include "DWARFDebugInfo.h"
-#include "LogChannelDWARF.h"
-#include "SymbolFileDWARF.h"
-
using namespace lldb;
using namespace lldb_private;
-//----------------------------------------------------------------------
// Constructor
-//----------------------------------------------------------------------
DWARFDebugAranges::DWARFDebugAranges() : m_aranges() {}
-//----------------------------------------------------------------------
// CountArangeDescriptors
-//----------------------------------------------------------------------
class CountArangeDescriptors {
public:
CountArangeDescriptors(uint32_t &count_ref) : count(count_ref) {
@@ -45,53 +30,36 @@ public:
uint32_t &count;
};
-//----------------------------------------------------------------------
// Extract
-//----------------------------------------------------------------------
-bool DWARFDebugAranges::Extract(const DWARFDataExtractor &debug_aranges_data) {
- if (debug_aranges_data.ValidOffset(0)) {
- lldb::offset_t offset = 0;
-
- DWARFDebugArangeSet set;
- Range range;
- while (set.Extract(debug_aranges_data, &offset)) {
- const uint32_t num_descriptors = set.NumDescriptors();
- if (num_descriptors > 0) {
- const dw_offset_t cu_offset = set.GetCompileUnitDIEOffset();
-
- for (uint32_t i = 0; i < num_descriptors; ++i) {
- const DWARFDebugArangeSet::Descriptor &descriptor =
- set.GetDescriptorRef(i);
- m_aranges.Append(RangeToDIE::Entry(descriptor.address,
- descriptor.length, cu_offset));
- }
+llvm::Error
+DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) {
+ lldb::offset_t offset = 0;
+
+ DWARFDebugArangeSet set;
+ Range range;
+ while (debug_aranges_data.ValidOffset(offset)) {
+ llvm::Error error = set.extract(debug_aranges_data, &offset);
+ if (!error)
+ return error;
+
+ const uint32_t num_descriptors = set.NumDescriptors();
+ if (num_descriptors > 0) {
+ const dw_offset_t cu_offset = set.GetHeader().cu_offset;
+
+ for (uint32_t i = 0; i < num_descriptors; ++i) {
+ const DWARFDebugArangeSet::Descriptor &descriptor =
+ set.GetDescriptorRef(i);
+ m_aranges.Append(RangeToDIE::Entry(descriptor.address,
+ descriptor.length, cu_offset));
}
- set.Clear();
}
+ set.Clear();
}
- return false;
-}
-
-//----------------------------------------------------------------------
-// Generate
-//----------------------------------------------------------------------
-bool DWARFDebugAranges::Generate(SymbolFileDWARF *dwarf2Data) {
- Clear();
- DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo();
- if (debug_info) {
- uint32_t cu_idx = 0;
- const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
- for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
- DWARFUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- if (cu)
- cu->BuildAddressRangeTable(dwarf2Data, this);
- }
- }
- return !IsEmpty();
+ return llvm::ErrorSuccess();
}
void DWARFDebugAranges::Dump(Log *log) const {
- if (log == NULL)
+ if (log == nullptr)
return;
const size_t num_entries = m_aranges.GetSize();
@@ -114,35 +82,11 @@ void DWARFDebugAranges::Sort(bool minimize) {
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
static_cast<void *>(this));
- Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
- size_t orig_arange_size = 0;
- if (log) {
- orig_arange_size = m_aranges.GetSize();
- log->Printf("DWARFDebugAranges::Sort(minimize = %u) with %" PRIu64
- " entries",
- minimize, (uint64_t)orig_arange_size);
- }
-
m_aranges.Sort();
m_aranges.CombineConsecutiveEntriesWithEqualData();
-
- if (log) {
- if (minimize) {
- const size_t new_arange_size = m_aranges.GetSize();
- const size_t delta = orig_arange_size - new_arange_size;
- log->Printf("DWARFDebugAranges::Sort() %" PRIu64
- " entries after minimizing (%" PRIu64
- " entries combined for %" PRIu64 " bytes saved)",
- (uint64_t)new_arange_size, (uint64_t)delta,
- (uint64_t)delta * sizeof(Range));
- }
- Dump(log);
- }
}
-//----------------------------------------------------------------------
// FindAddress
-//----------------------------------------------------------------------
dw_offset_t DWARFDebugAranges::FindAddress(dw_addr_t address) const {
const RangeToDIE::Entry *entry = m_aranges.FindEntryThatContains(address);
if (entry)
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
index e7a8635f0532..74ba011b27af 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
@@ -1,21 +1,17 @@
//===-- DWARFDebugAranges.h -------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef SymbolFileDWARF_DWARFDebugAranges_h_
#define SymbolFileDWARF_DWARFDebugAranges_h_
-#include "DWARFDebugArangeSet.h"
-#include <list>
-
-#include "lldb/Core/RangeMap.h"
-
-class SymbolFileDWARF;
+#include "lldb/Core/dwarf.h"
+#include "lldb/Utility/RangeMap.h"
+#include "llvm/Support/Error.h"
class DWARFDebugAranges {
protected:
@@ -30,19 +26,14 @@ public:
void Clear() { m_aranges.Clear(); }
- bool Extract(const lldb_private::DWARFDataExtractor &debug_aranges_data);
-
- bool Generate(SymbolFileDWARF *dwarf2Data);
+ llvm::Error
+ extract(const lldb_private::DWARFDataExtractor &debug_aranges_data);
// Use append range multiple times and then call sort
void AppendRange(dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc);
void Sort(bool minimize);
- const Range *RangeAtIndex(uint32_t idx) const {
- return m_aranges.GetEntryAtIndex(idx);
- }
-
void Dump(lldb_private::Log *log) const;
dw_offset_t FindAddress(dw_addr_t address) const;
@@ -57,8 +48,6 @@ public:
return DW_INVALID_OFFSET;
}
- static void Dump(SymbolFileDWARF *dwarf2Data, lldb_private::Stream *s);
-
protected:
RangeToDIE m_aranges;
};
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index dadc30dc918a..100f35f8c6b0 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -1,9 +1,8 @@
//===-- DWARFDebugInfo.cpp --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -16,213 +15,183 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
+#include "llvm/Support/Casting.h"
#include "DWARFCompileUnit.h"
-#include "DWARFDebugAranges.h"
+#include "DWARFContext.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFFormValue.h"
-#include "LogChannelDWARF.h"
+#include "DWARFTypeUnit.h"
using namespace lldb;
using namespace lldb_private;
using namespace std;
-//----------------------------------------------------------------------
// Constructor
-//----------------------------------------------------------------------
-DWARFDebugInfo::DWARFDebugInfo()
- : m_dwarf2Data(NULL), m_compile_units(), m_cu_aranges_ap() {}
-
-//----------------------------------------------------------------------
-// SetDwarfData
-//----------------------------------------------------------------------
-void DWARFDebugInfo::SetDwarfData(SymbolFileDWARF *dwarf2Data) {
- m_dwarf2Data = dwarf2Data;
- m_compile_units.clear();
-}
+DWARFDebugInfo::DWARFDebugInfo(SymbolFileDWARF &dwarf,
+ lldb_private::DWARFContext &context)
+ : m_dwarf(dwarf), m_context(context), m_units(), m_cu_aranges_up() {}
+
+llvm::Expected<DWARFDebugAranges &> DWARFDebugInfo::GetCompileUnitAranges() {
+ if (m_cu_aranges_up)
+ return *m_cu_aranges_up;
+
+ m_cu_aranges_up = llvm::make_unique<DWARFDebugAranges>();
+ const DWARFDataExtractor &debug_aranges_data =
+ m_context.getOrLoadArangesData();
+ if (llvm::Error error = m_cu_aranges_up->extract(debug_aranges_data))
+ return std::move(error);
+
+ // Make a list of all CUs represented by the arange data in the file.
+ std::set<dw_offset_t> cus_with_data;
+ for (size_t n = 0; n < m_cu_aranges_up->GetNumRanges(); n++) {
+ dw_offset_t offset = m_cu_aranges_up->OffsetAtIndex(n);
+ if (offset != DW_INVALID_OFFSET)
+ cus_with_data.insert(offset);
+ }
-DWARFDebugAranges &DWARFDebugInfo::GetCompileUnitAranges() {
- if (m_cu_aranges_ap.get() == NULL && m_dwarf2Data) {
- Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
-
- m_cu_aranges_ap.reset(new DWARFDebugAranges());
- const DWARFDataExtractor &debug_aranges_data =
- m_dwarf2Data->get_debug_aranges_data();
- if (debug_aranges_data.GetByteSize() > 0) {
- if (log)
- log->Printf(
- "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" from "
- ".debug_aranges",
- m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
- m_cu_aranges_ap->Extract(debug_aranges_data);
- }
+ // Manually build arange data for everything that wasn't in the
+ // .debug_aranges table.
+ const size_t num_units = GetNumUnits();
+ for (size_t idx = 0; idx < num_units; ++idx) {
+ DWARFUnit *cu = GetUnitAtIndex(idx);
- // Make a list of all CUs represented by the arange data in the file.
- std::set<dw_offset_t> cus_with_data;
- for (size_t n = 0; n < m_cu_aranges_ap.get()->GetNumRanges(); n++) {
- dw_offset_t offset = m_cu_aranges_ap.get()->OffsetAtIndex(n);
- if (offset != DW_INVALID_OFFSET)
- cus_with_data.insert(offset);
- }
+ dw_offset_t offset = cu->GetOffset();
+ if (cus_with_data.find(offset) == cus_with_data.end())
+ cu->BuildAddressRangeTable(m_cu_aranges_up.get());
+ }
+
+ const bool minimize = true;
+ m_cu_aranges_up->Sort(minimize);
+ return *m_cu_aranges_up;
+}
- // Manually build arange data for everything that wasn't in the
- // .debug_aranges table.
- bool printed = false;
- const size_t num_compile_units = GetNumCompileUnits();
- for (size_t idx = 0; idx < num_compile_units; ++idx) {
- DWARFUnit *cu = GetCompileUnitAtIndex(idx);
-
- dw_offset_t offset = cu->GetOffset();
- if (cus_with_data.find(offset) == cus_with_data.end()) {
- if (log) {
- if (!printed)
- log->Printf(
- "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" by parsing",
- m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
- printed = true;
- }
- cu->BuildAddressRangeTable(m_dwarf2Data, m_cu_aranges_ap.get());
- }
+void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) {
+ DWARFDataExtractor data = section == DIERef::Section::DebugTypes
+ ? m_context.getOrLoadDebugTypesData()
+ : m_context.getOrLoadDebugInfoData();
+ lldb::offset_t offset = 0;
+ while (data.ValidOffset(offset)) {
+ llvm::Expected<DWARFUnitSP> unit_sp =
+ DWARFUnit::extract(m_dwarf, m_units.size(), data, section, &offset);
+
+ if (!unit_sp) {
+ // FIXME: Propagate this error up.
+ llvm::consumeError(unit_sp.takeError());
+ return;
}
- const bool minimize = true;
- m_cu_aranges_ap->Sort(minimize);
- }
- return *m_cu_aranges_ap.get();
-}
+ // If it didn't return an error, then it should be returning a valid Unit.
+ assert(*unit_sp);
+ m_units.push_back(*unit_sp);
+ offset = (*unit_sp)->GetNextUnitOffset();
-void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() {
- if (m_compile_units.empty()) {
- if (m_dwarf2Data != NULL) {
- lldb::offset_t offset = 0;
- DWARFUnitSP cu_sp;
- const auto &debug_info_data = m_dwarf2Data->get_debug_info_data();
- while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data,
- &offset))) {
- m_compile_units.push_back(cu_sp);
-
- offset = cu_sp->GetNextCompileUnitOffset();
- }
+ if (auto *type_unit = llvm::dyn_cast<DWARFTypeUnit>(unit_sp->get())) {
+ m_type_hash_to_unit_index.emplace_back(type_unit->GetTypeHash(),
+ unit_sp.get()->GetID());
}
}
}
-size_t DWARFDebugInfo::GetNumCompileUnits() {
- ParseCompileUnitHeadersIfNeeded();
- return m_compile_units.size();
-}
+void DWARFDebugInfo::ParseUnitHeadersIfNeeded() {
+ if (!m_units.empty())
+ return;
-DWARFUnit *DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx) {
- DWARFUnit *cu = NULL;
- if (idx < GetNumCompileUnits())
- cu = m_compile_units[idx].get();
- return cu;
+ ParseUnitsFor(DIERef::Section::DebugInfo);
+ ParseUnitsFor(DIERef::Section::DebugTypes);
+ llvm::sort(m_type_hash_to_unit_index, llvm::less_first());
}
-bool DWARFDebugInfo::ContainsCompileUnit(const DWARFUnit *cu) const {
- // Not a verify efficient function, but it is handy for use in assertions to
- // make sure that a compile unit comes from a debug information file.
- CompileUnitColl::const_iterator end_pos = m_compile_units.end();
- CompileUnitColl::const_iterator pos;
+size_t DWARFDebugInfo::GetNumUnits() {
+ ParseUnitHeadersIfNeeded();
+ return m_units.size();
+}
- for (pos = m_compile_units.begin(); pos != end_pos; ++pos) {
- if (pos->get() == cu)
- return true;
- }
- return false;
+DWARFUnit *DWARFDebugInfo::GetUnitAtIndex(user_id_t idx) {
+ DWARFUnit *cu = nullptr;
+ if (idx < GetNumUnits())
+ cu = m_units[idx].get();
+ return cu;
}
-bool DWARFDebugInfo::OffsetLessThanCompileUnitOffset(
- dw_offset_t offset, const DWARFUnitSP &cu_sp) {
- return offset < cu_sp->GetOffset();
+uint32_t DWARFDebugInfo::FindUnitIndex(DIERef::Section section,
+ dw_offset_t offset) {
+ ParseUnitHeadersIfNeeded();
+
+ // llvm::lower_bound is not used as for DIE offsets it would still return
+ // index +1 and GetOffset() returning index itself would be a special case.
+ auto pos = llvm::upper_bound(
+ m_units, std::make_pair(section, offset),
+ [](const std::pair<DIERef::Section, dw_offset_t> &lhs,
+ const DWARFUnitSP &rhs) {
+ return lhs < std::make_pair(rhs->GetDebugSection(), rhs->GetOffset());
+ });
+ uint32_t idx = std::distance(m_units.begin(), pos);
+ if (idx == 0)
+ return DW_INVALID_OFFSET;
+ return idx - 1;
}
-DWARFUnit *DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset,
- uint32_t *idx_ptr) {
- DWARFUnitSP cu_sp;
- uint32_t cu_idx = DW_INVALID_INDEX;
- if (cu_offset != DW_INVALID_OFFSET) {
- ParseCompileUnitHeadersIfNeeded();
-
- // Watch out for single compile unit executable as they are pretty common
- const size_t num_cus = m_compile_units.size();
- if (num_cus == 1) {
- if (m_compile_units[0]->GetOffset() == cu_offset) {
- cu_sp = m_compile_units[0];
- cu_idx = 0;
- }
- } else if (num_cus) {
- CompileUnitColl::const_iterator end_pos = m_compile_units.end();
- CompileUnitColl::const_iterator begin_pos = m_compile_units.begin();
- CompileUnitColl::const_iterator pos = std::upper_bound(
- begin_pos, end_pos, cu_offset, OffsetLessThanCompileUnitOffset);
- if (pos != begin_pos) {
- --pos;
- if ((*pos)->GetOffset() == cu_offset) {
- cu_sp = *pos;
- cu_idx = std::distance(begin_pos, pos);
- }
- }
- }
+DWARFUnit *DWARFDebugInfo::GetUnitAtOffset(DIERef::Section section,
+ dw_offset_t cu_offset,
+ uint32_t *idx_ptr) {
+ uint32_t idx = FindUnitIndex(section, cu_offset);
+ DWARFUnit *result = GetUnitAtIndex(idx);
+ if (result && result->GetOffset() != cu_offset) {
+ result = nullptr;
+ idx = DW_INVALID_INDEX;
}
if (idx_ptr)
- *idx_ptr = cu_idx;
- return cu_sp.get();
+ *idx_ptr = idx;
+ return result;
}
-DWARFUnit *DWARFDebugInfo::GetCompileUnit(const DIERef &die_ref) {
- if (die_ref.cu_offset == DW_INVALID_OFFSET)
- return GetCompileUnitContainingDIEOffset(die_ref.die_offset);
- else
- return GetCompileUnit(die_ref.cu_offset);
+DWARFUnit *DWARFDebugInfo::GetUnit(const DIERef &die_ref) {
+ return GetUnitContainingDIEOffset(die_ref.section(), die_ref.die_offset());
}
DWARFUnit *
-DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset) {
- ParseCompileUnitHeadersIfNeeded();
-
- DWARFUnitSP cu_sp;
-
- // Watch out for single compile unit executable as they are pretty common
- const size_t num_cus = m_compile_units.size();
- if (num_cus == 1) {
- if (m_compile_units[0]->ContainsDIEOffset(die_offset))
- return m_compile_units[0].get();
- } else if (num_cus) {
- CompileUnitColl::const_iterator end_pos = m_compile_units.end();
- CompileUnitColl::const_iterator begin_pos = m_compile_units.begin();
- CompileUnitColl::const_iterator pos = std::upper_bound(
- begin_pos, end_pos, die_offset, OffsetLessThanCompileUnitOffset);
- if (pos != begin_pos) {
- --pos;
- if ((*pos)->ContainsDIEOffset(die_offset))
- return (*pos).get();
- }
- }
+DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section,
+ dw_offset_t die_offset) {
+ uint32_t idx = FindUnitIndex(section, die_offset);
+ DWARFUnit *result = GetUnitAtIndex(idx);
+ if (result && !result->ContainsDIEOffset(die_offset))
+ return nullptr;
+ return result;
+}
+
+DWARFTypeUnit *DWARFDebugInfo::GetTypeUnitForHash(uint64_t hash) {
+ auto pos = llvm::lower_bound(m_type_hash_to_unit_index,
+ std::make_pair(hash, 0u), llvm::less_first());
+ if (pos == m_type_hash_to_unit_index.end() || pos->first != hash)
+ return nullptr;
+ return llvm::cast<DWARFTypeUnit>(GetUnitAtIndex(pos->second));
+}
- return nullptr;
+bool DWARFDebugInfo::ContainsTypeUnits() {
+ ParseUnitHeadersIfNeeded();
+ return !m_type_hash_to_unit_index.empty();
}
DWARFDIE
-DWARFDebugInfo::GetDIEForDIEOffset(dw_offset_t die_offset) {
- DWARFUnit *cu = GetCompileUnitContainingDIEOffset(die_offset);
+DWARFDebugInfo::GetDIEForDIEOffset(DIERef::Section section,
+ dw_offset_t die_offset) {
+ DWARFUnit *cu = GetUnitContainingDIEOffset(section, die_offset);
if (cu)
return cu->GetDIE(die_offset);
return DWARFDIE();
}
-//----------------------------------------------------------------------
// GetDIE()
//
// Get the DIE (Debug Information Entry) with the specified offset.
-//----------------------------------------------------------------------
DWARFDIE
DWARFDebugInfo::GetDIE(const DIERef &die_ref) {
- DWARFUnit *cu = GetCompileUnit(die_ref);
+ DWARFUnit *cu = GetUnit(die_ref);
if (cu)
- return cu->GetDIE(die_ref.die_offset);
+ return cu->GetDIE(die_ref.die_offset());
return DWARFDIE(); // Not found
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index fc6085f99a21..d1b066ffe80c 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -1,9 +1,8 @@
//===-- DWARFDebugInfo.h ----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -13,11 +12,17 @@
#include <map>
#include <vector>
-#include "DWARFUnit.h"
#include "DWARFDIE.h"
+#include "DWARFTypeUnit.h"
+#include "DWARFUnit.h"
#include "SymbolFileDWARF.h"
#include "lldb/Core/STLUtils.h"
#include "lldb/lldb-private.h"
+#include "llvm/Support/Error.h"
+
+namespace lldb_private {
+class DWARFContext;
+}
typedef std::multimap<const char *, dw_offset_t, CStringCompareFunctionObject>
CStringToDIEMap;
@@ -32,16 +37,20 @@ public:
const dw_offset_t next_offset,
const uint32_t depth, void *userData);
- DWARFDebugInfo();
- void SetDwarfData(SymbolFileDWARF *dwarf2Data);
+ explicit DWARFDebugInfo(SymbolFileDWARF &dwarf,
+ lldb_private::DWARFContext &context);
- size_t GetNumCompileUnits();
- bool ContainsCompileUnit(const DWARFUnit *cu) const;
- DWARFUnit *GetCompileUnitAtIndex(uint32_t idx);
- DWARFUnit *GetCompileUnit(dw_offset_t cu_offset, uint32_t *idx_ptr = NULL);
- DWARFUnit *GetCompileUnitContainingDIEOffset(dw_offset_t die_offset);
- DWARFUnit *GetCompileUnit(const DIERef &die_ref);
- DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset);
+ size_t GetNumUnits();
+ DWARFUnit *GetUnitAtIndex(lldb::user_id_t idx);
+ DWARFUnit *GetUnitAtOffset(DIERef::Section section, dw_offset_t cu_offset,
+ uint32_t *idx_ptr = nullptr);
+ DWARFUnit *GetUnitContainingDIEOffset(DIERef::Section section,
+ dw_offset_t die_offset);
+ DWARFUnit *GetUnit(const DIERef &die_ref);
+ DWARFTypeUnit *GetTypeUnitForHash(uint64_t hash);
+ bool ContainsTypeUnits();
+ DWARFDIE GetDIEForDIEOffset(DIERef::Section section,
+ dw_offset_t die_offset);
DWARFDIE GetDIE(const DIERef &die_ref);
enum {
@@ -51,26 +60,27 @@ public:
(1 << 2) // Show all parent DIEs when dumping single DIEs
};
- DWARFDebugAranges &GetCompileUnitAranges();
+ llvm::Expected<DWARFDebugAranges &> GetCompileUnitAranges();
protected:
- static bool OffsetLessThanCompileUnitOffset(dw_offset_t offset,
- const DWARFUnitSP &cu_sp);
+ typedef std::vector<DWARFUnitSP> UnitColl;
- typedef std::vector<DWARFUnitSP> CompileUnitColl;
-
- //----------------------------------------------------------------------
- // Member variables
- //----------------------------------------------------------------------
- SymbolFileDWARF *m_dwarf2Data;
- CompileUnitColl m_compile_units;
+ SymbolFileDWARF &m_dwarf;
+ lldb_private::DWARFContext &m_context;
+ UnitColl m_units;
std::unique_ptr<DWARFDebugAranges>
- m_cu_aranges_ap; // A quick address to compile unit table
+ m_cu_aranges_up; // A quick address to compile unit table
+
+ std::vector<std::pair<uint64_t, uint32_t>> m_type_hash_to_unit_index;
private:
// All parsing needs to be done partially any managed by this class as
// accessors are called.
- void ParseCompileUnitHeadersIfNeeded();
+ void ParseUnitHeadersIfNeeded();
+
+ void ParseUnitsFor(DIERef::Section section);
+
+ uint32_t FindUnitIndex(DIERef::Section section, dw_offset_t offset);
DISALLOW_COPY_AND_ASSIGN(DWARFDebugInfo);
};
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 7531aeac709a..2f55b7d40ed9 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -1,9 +1,8 @@
//===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -13,19 +12,21 @@
#include <algorithm>
+#include "llvm/Support/LEB128.h"
+
#include "lldb/Core/Module.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/Stream.h"
-#include "DWARFUnit.h"
-#include "DWARFDIECollection.h"
+#include "DWARFCompileUnit.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
#include "DWARFFormValue.h"
+#include "DWARFUnit.h"
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDwo.h"
@@ -33,14 +34,15 @@ using namespace lldb_private;
using namespace std;
extern int g_verbose;
-bool DWARFDebugInfoEntry::FastExtract(
- const DWARFDataExtractor &debug_info_data, const DWARFUnit *cu,
- const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
- lldb::offset_t *offset_ptr) {
+// Extract a debug info entry for a given DWARFUnit from the data
+// starting at the offset in offset_ptr
+bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
+ const DWARFUnit *cu,
+ lldb::offset_t *offset_ptr) {
m_offset = *offset_ptr;
m_parent_idx = 0;
m_sibling_idx = 0;
- const uint64_t abbr_idx = debug_info_data.GetULEB128(offset_ptr);
+ const uint64_t abbr_idx = data.GetULEB128(offset_ptr);
lldbassert(abbr_idx <= UINT16_MAX);
m_abbr_idx = abbr_idx;
@@ -49,12 +51,9 @@ bool DWARFDebugInfoEntry::FastExtract(
if (m_abbr_idx) {
lldb::offset_t offset = *offset_ptr;
-
- const DWARFAbbreviationDeclaration *abbrevDecl =
- cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);
-
- if (abbrevDecl == NULL) {
- cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
+ const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
+ if (abbrevDecl == nullptr) {
+ cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
"{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
"attach the file at the start of this error message",
m_offset, (unsigned)abbr_idx);
@@ -64,16 +63,16 @@ bool DWARFDebugInfoEntry::FastExtract(
}
m_tag = abbrevDecl->Tag();
m_has_children = abbrevDecl->HasChildren();
- // Skip all data in the .debug_info for the attributes
+ // Skip all data in the .debug_info or .debug_types for the attributes
const uint32_t numAttributes = abbrevDecl->NumAttributes();
uint32_t i;
dw_form_t form;
for (i = 0; i < numAttributes; ++i) {
form = abbrevDecl->GetFormByIndexUnchecked(i);
-
- const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
+ llvm::Optional<uint8_t> fixed_skip_size =
+ DWARFFormValue::GetFixedSize(form, cu);
if (fixed_skip_size)
- offset += fixed_skip_size;
+ offset += *fixed_skip_size;
else {
bool form_is_indirect = false;
do {
@@ -81,24 +80,24 @@ bool DWARFDebugInfoEntry::FastExtract(
uint32_t form_size = 0;
switch (form) {
// Blocks if inlined data that have a length field and the data bytes
- // inlined in the .debug_info
+ // inlined in the .debug_info/.debug_types
case DW_FORM_exprloc:
case DW_FORM_block:
- form_size = debug_info_data.GetULEB128(&offset);
+ form_size = data.GetULEB128(&offset);
break;
case DW_FORM_block1:
- form_size = debug_info_data.GetU8_unchecked(&offset);
+ form_size = data.GetU8_unchecked(&offset);
break;
case DW_FORM_block2:
- form_size = debug_info_data.GetU16_unchecked(&offset);
+ form_size = data.GetU16_unchecked(&offset);
break;
case DW_FORM_block4:
- form_size = debug_info_data.GetU32_unchecked(&offset);
+ form_size = data.GetU32_unchecked(&offset);
break;
// Inlined NULL terminated C-strings
case DW_FORM_string:
- debug_info_data.GetCStr(&offset);
+ data.GetCStr(&offset);
break;
// Compile unit address sized values
@@ -109,7 +108,7 @@ bool DWARFDebugInfoEntry::FastExtract(
if (cu->GetVersion() <= 2)
form_size = cu->GetAddressByteSize();
else
- form_size = cu->IsDWARF64() ? 8 : 4;
+ form_size = 4;
break;
// 0 sized form
@@ -164,20 +163,17 @@ bool DWARFDebugInfoEntry::FastExtract(
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
case DW_FORM_strx:
- debug_info_data.Skip_LEB128(&offset);
+ data.Skip_LEB128(&offset);
break;
case DW_FORM_indirect:
form_is_indirect = true;
- form = debug_info_data.GetULEB128(&offset);
+ form = data.GetULEB128(&offset);
break;
case DW_FORM_strp:
case DW_FORM_sec_offset:
- if (cu->IsDWARF64())
- debug_info_data.GetU64(&offset);
- else
- debug_info_data.GetU32(&offset);
+ data.GetU32(&offset);
break;
case DW_FORM_implicit_const:
@@ -204,233 +200,48 @@ bool DWARFDebugInfoEntry::FastExtract(
return false;
}
-//----------------------------------------------------------------------
-// Extract
-//
-// Extract a debug info entry for a given compile unit from the .debug_info and
-// .debug_abbrev data within the SymbolFileDWARF class starting at the given
-// offset
-//----------------------------------------------------------------------
-bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu,
- lldb::offset_t *offset_ptr) {
- const DWARFDataExtractor &debug_info_data = cu->GetData();
- // const DWARFDataExtractor& debug_str_data =
- // dwarf2Data->get_debug_str_data();
- const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
- lldb::offset_t offset = *offset_ptr;
- // if (offset >= cu_end_offset)
- // Log::Status("DIE at offset 0x%8.8x is beyond the end of the current
- // compile unit (0x%8.8x)", m_offset, cu_end_offset);
- if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) {
- m_offset = offset;
-
- const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
- lldbassert(abbr_idx <= UINT16_MAX);
- m_abbr_idx = abbr_idx;
- if (abbr_idx) {
- const DWARFAbbreviationDeclaration *abbrevDecl =
- cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx);
-
- if (abbrevDecl) {
- m_tag = abbrevDecl->Tag();
- m_has_children = abbrevDecl->HasChildren();
-
- bool isCompileUnitTag = (m_tag == DW_TAG_compile_unit ||
- m_tag == DW_TAG_partial_unit);
- if (cu && isCompileUnitTag)
- const_cast<DWARFUnit *>(cu)->SetBaseAddress(0);
-
- // Skip all data in the .debug_info for the attributes
- const uint32_t numAttributes = abbrevDecl->NumAttributes();
- for (uint32_t i = 0; i < numAttributes; ++i) {
- DWARFFormValue form_value(cu);
- dw_attr_t attr;
- abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
- dw_form_t form = form_value.Form();
-
- if (isCompileUnitTag &&
- ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) {
- if (form_value.ExtractValue(debug_info_data, &offset)) {
- if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
- const_cast<DWARFUnit *>(cu)->SetBaseAddress(
- form_value.Address());
- }
- } else {
- bool form_is_indirect = false;
- do {
- form_is_indirect = false;
- uint32_t form_size = 0;
- switch (form) {
- // Blocks if inlined data that have a length field and the data
- // bytes inlined in the .debug_info
- case DW_FORM_exprloc:
- case DW_FORM_block:
- form_size = debug_info_data.GetULEB128(&offset);
- break;
- case DW_FORM_block1:
- form_size = debug_info_data.GetU8(&offset);
- break;
- case DW_FORM_block2:
- form_size = debug_info_data.GetU16(&offset);
- break;
- case DW_FORM_block4:
- form_size = debug_info_data.GetU32(&offset);
- break;
-
- // Inlined NULL terminated C-strings
- case DW_FORM_string:
- debug_info_data.GetCStr(&offset);
- break;
-
- // Compile unit address sized values
- case DW_FORM_addr:
- form_size = cu->GetAddressByteSize();
- break;
- case DW_FORM_ref_addr:
- if (cu->GetVersion() <= 2)
- form_size = cu->GetAddressByteSize();
- else
- form_size = cu->IsDWARF64() ? 8 : 4;
- break;
-
- // 0 sized form
- case DW_FORM_flag_present:
- case DW_FORM_implicit_const:
- form_size = 0;
- break;
-
- // 1 byte values
- case DW_FORM_data1:
- case DW_FORM_flag:
- case DW_FORM_ref1:
- form_size = 1;
- break;
-
- // 2 byte values
- case DW_FORM_data2:
- case DW_FORM_ref2:
- form_size = 2;
- break;
-
- // 4 byte values
- case DW_FORM_data4:
- case DW_FORM_ref4:
- form_size = 4;
- break;
-
- // 8 byte values
- case DW_FORM_data8:
- case DW_FORM_ref8:
- case DW_FORM_ref_sig8:
- form_size = 8;
- break;
-
- // signed or unsigned LEB 128 values
- case DW_FORM_sdata:
- case DW_FORM_udata:
- case DW_FORM_ref_udata:
- case DW_FORM_GNU_addr_index:
- case DW_FORM_GNU_str_index:
- debug_info_data.Skip_LEB128(&offset);
- break;
-
- case DW_FORM_indirect:
- form = debug_info_data.GetULEB128(&offset);
- form_is_indirect = true;
- break;
-
- case DW_FORM_strp:
- case DW_FORM_sec_offset:
- if (cu->IsDWARF64())
- debug_info_data.GetU64(&offset);
- else
- debug_info_data.GetU32(&offset);
- break;
-
- default:
- *offset_ptr = offset;
- return false;
- }
-
- offset += form_size;
- } while (form_is_indirect);
- }
- }
- *offset_ptr = offset;
- return true;
- }
- } else {
- m_tag = 0;
- m_has_children = false;
- *offset_ptr = offset;
- return true; // NULL debug tag entry
- }
- }
-
- return false;
-}
-
-//----------------------------------------------------------------------
-// DumpAncestry
-//
-// Dumps all of a debug information entries parents up until oldest and all of
-// it's attributes to the specified stream.
-//----------------------------------------------------------------------
-void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu,
- const DWARFDebugInfoEntry *oldest,
- Stream &s,
- uint32_t recurse_depth) const {
- const DWARFDebugInfoEntry *parent = GetParent();
- if (parent && parent != oldest)
- parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0);
- Dump(dwarf2Data, cu, s, recurse_depth);
+static DWARFRangeList GetRangesOrReportError(const DWARFUnit &unit,
+ const DWARFDebugInfoEntry &die,
+ const DWARFFormValue &value) {
+ llvm::Expected<DWARFRangeList> expected_ranges =
+ (value.Form() == DW_FORM_rnglistx)
+ ? unit.FindRnglistFromIndex(value.Unsigned())
+ : unit.FindRnglistFromOffset(value.Unsigned());
+ if (expected_ranges)
+ return std::move(*expected_ranges);
+ unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+ "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute, but "
+ "range extraction failed (%s), please file a bug "
+ "and attach the file at the start of this error message",
+ die.GetOffset(), value.Unsigned(),
+ toString(expected_ranges.takeError()).c_str());
+ return DWARFRangeList();
}
-static dw_offset_t GetRangesOffset(const DWARFDebugRangesBase *debug_ranges,
- DWARFFormValue &form_value) {
- if (form_value.Form() == DW_FORM_rnglistx)
- return debug_ranges->GetOffset(form_value.Unsigned());
- return form_value.Unsigned();
-}
-
-//----------------------------------------------------------------------
// GetDIENamesAndRanges
//
// Gets the valid address ranges for a given DIE by looking for a
// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
-//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const char *&name,
- const char *&mangled, DWARFRangeList &ranges, int &decl_file,
- int &decl_line, int &decl_column, int &call_file, int &call_line,
- int &call_column, DWARFExpression *frame_base) const {
- if (dwarf2Data == nullptr)
- return false;
-
- SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
- if (dwo_symbol_file)
- return GetDIENamesAndRanges(
- dwo_symbol_file, dwo_symbol_file->GetCompileUnit(), name, mangled,
- ranges, decl_file, decl_line, decl_column, call_file, call_line,
- call_column, frame_base);
-
+ const DWARFUnit *cu, const char *&name, const char *&mangled,
+ DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column,
+ int &call_file, int &call_line, int &call_column,
+ DWARFExpression *frame_base) const {
dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- std::vector<DIERef> die_refs;
+ std::vector<DWARFDIE> dies;
bool set_frame_base_loclist_addr = false;
- lldb::offset_t offset;
- const DWARFAbbreviationDeclaration *abbrevDecl =
- GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
+ const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
- lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
+ SymbolFileDWARF &dwarf = cu->GetSymbolFileDWARF();
+ lldb::ModuleSP module = dwarf.GetObjectFile()->GetModule();
if (abbrevDecl) {
- const DWARFDataExtractor &debug_info_data = cu->GetData();
+ const DWARFDataExtractor &data = cu->GetData();
+ lldb::offset_t offset = GetFirstAttributeOffset();
- if (!debug_info_data.ValidOffset(offset))
+ if (!data.ValidOffset(offset))
return false;
const uint32_t numAttributes = abbrevDecl->NumAttributes();
@@ -441,7 +252,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
dw_attr_t attr;
abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
- if (form_value.ExtractValue(debug_info_data, &offset)) {
+ if (form_value.ExtractValue(data, &offset)) {
switch (attr) {
case DW_AT_low_pc:
lo_pc = form_value.Address();
@@ -457,6 +268,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
case DW_AT_high_pc:
if (form_value.Form() == DW_FORM_addr ||
+ form_value.Form() == DW_FORM_addrx ||
form_value.Form() == DW_FORM_GNU_addr_index) {
hi_pc = form_value.Address();
} else {
@@ -469,35 +281,27 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
}
break;
- case DW_AT_ranges: {
- const DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges();
- if (debug_ranges)
- debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), ranges);
- else
- cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
- "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64
- ") attribute yet DWARF has no .debug_ranges, please file a bug "
- "and attach the file at the start of this error message",
- m_offset, form_value.Unsigned());
- } break;
+ case DW_AT_ranges:
+ ranges = GetRangesOrReportError(*cu, *this, form_value);
+ break;
case DW_AT_name:
- if (name == NULL)
+ if (name == nullptr)
name = form_value.AsCString();
break;
case DW_AT_MIPS_linkage_name:
case DW_AT_linkage_name:
- if (mangled == NULL)
+ if (mangled == nullptr)
mangled = form_value.AsCString();
break;
case DW_AT_abstract_origin:
- die_refs.emplace_back(form_value);
+ dies.push_back(form_value.Reference());
break;
case DW_AT_specification:
- die_refs.emplace_back(form_value);
+ dies.push_back(form_value.Reference());
break;
case DW_AT_decl_file:
@@ -534,20 +338,20 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
if (frame_base) {
if (form_value.BlockData()) {
uint32_t block_offset =
- form_value.BlockData() - debug_info_data.GetDataStart();
+ form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- frame_base->SetOpcodeData(module, debug_info_data, block_offset,
- block_length);
+ *frame_base = DWARFExpression(module, data, cu,
+ block_offset, block_length);
} else {
- const DWARFDataExtractor &debug_loc_data =
- dwarf2Data->DebugLocData();
+ const DWARFDataExtractor &debug_loc_data = dwarf.DebugLocData();
const dw_offset_t debug_loc_offset = form_value.Unsigned();
size_t loc_list_length = DWARFExpression::LocationListSize(
cu, debug_loc_data, debug_loc_offset);
if (loc_list_length > 0) {
- frame_base->SetOpcodeData(module, debug_loc_data,
- debug_loc_offset, loc_list_length);
+ *frame_base =
+ DWARFExpression(module, debug_loc_data, cu,
+ debug_loc_offset, loc_list_length);
if (lo_pc != LLDB_INVALID_ADDRESS) {
assert(lo_pc >= cu->GetBaseAddress());
frame_base->SetLocationListSlide(lo_pc -
@@ -582,56 +386,48 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
frame_base->SetLocationListSlide(lowest_range_pc - cu->GetBaseAddress());
}
- if (ranges.IsEmpty() || name == NULL || mangled == NULL) {
- for (const DIERef &die_ref : die_refs) {
- if (die_ref.die_offset != DW_INVALID_OFFSET) {
- DWARFDIE die = dwarf2Data->GetDIE(die_ref);
- if (die)
- die.GetDIE()->GetDIENamesAndRanges(
- die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file,
- decl_line, decl_column, call_file, call_line, call_column);
+ if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) {
+ for (const DWARFDIE &die : dies) {
+ if (die) {
+ die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
+ decl_file, decl_line, decl_column,
+ call_file, call_line, call_column);
}
}
}
return !ranges.IsEmpty();
}
-//----------------------------------------------------------------------
// Dump
//
// Dumps a debug information entry and all of it's attributes to the specified
// stream.
-//----------------------------------------------------------------------
-void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu, Stream &s,
+void DWARFDebugInfoEntry::Dump(const DWARFUnit *cu, Stream &s,
uint32_t recurse_depth) const {
- const DWARFDataExtractor &debug_info_data = cu->GetData();
+ const DWARFDataExtractor &data = cu->GetData();
lldb::offset_t offset = m_offset;
- if (debug_info_data.ValidOffset(offset)) {
- dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
+ if (data.ValidOffset(offset)) {
+ dw_uleb128_t abbrCode = data.GetULEB128(&offset);
s.Printf("\n0x%8.8x: ", m_offset);
s.Indent();
if (abbrCode != m_abbr_idx) {
s.Printf("error: DWARF has been modified\n");
} else if (abbrCode) {
- const DWARFAbbreviationDeclaration *abbrevDecl =
- cu->GetAbbreviations()->GetAbbreviationDeclaration(abbrCode);
-
+ const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
if (abbrevDecl) {
s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' ');
- // Dump all data in the .debug_info for the attributes
+ // Dump all data in the .debug_info/.debug_types for the attributes
const uint32_t numAttributes = abbrevDecl->NumAttributes();
for (uint32_t i = 0; i < numAttributes; ++i) {
DWARFFormValue form_value(cu);
dw_attr_t attr;
abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
- DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr,
- form_value);
+ DumpAttribute(cu, data, &offset, s, attr, form_value);
}
const DWARFDebugInfoEntry *child = GetFirstChild();
@@ -639,7 +435,7 @@ void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
s.IndentMore();
while (child) {
- child->Dump(dwarf2Data, cu, s, recurse_depth - 1);
+ child->Dump(cu, s, recurse_depth - 1);
child = child->GetSibling();
}
s.IndentLess();
@@ -654,34 +450,15 @@ void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
}
}
-void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data,
- DWARFUnit *cu, Stream &s) const {
- const DWARFBaseDIE cu_die = cu->GetUnitDIEOnly();
- const char *cu_name = NULL;
- if (cu_die)
- cu_name = cu_die.GetName();
- const char *obj_file_name = NULL;
- ObjectFile *obj_file = dwarf2Data->GetObjectFile();
- if (obj_file)
- obj_file_name =
- obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>");
- const char *die_name = GetName(dwarf2Data, cu);
- s.Printf("0x%8.8x/0x%8.8x: %-30s (from %s in %s)", cu->GetOffset(),
- GetOffset(), die_name ? die_name : "", cu_name ? cu_name : "<NULL>",
- obj_file_name ? obj_file_name : "<NULL>");
-}
-
-//----------------------------------------------------------------------
// DumpAttribute
//
// Dumps a debug information entry attribute along with it's form. Any special
// display of attributes is done (disassemble location lists, show enumeration
// values for attributes, etc).
-//----------------------------------------------------------------------
void DWARFDebugInfoEntry::DumpAttribute(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr,
- Stream &s, dw_attr_t attr, DWARFFormValue &form_value) {
+ const DWARFUnit *cu, const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr, Stream &s, dw_attr_t attr,
+ DWARFFormValue &form_value) {
bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
s.Printf(" ");
@@ -691,7 +468,7 @@ void DWARFDebugInfoEntry::DumpAttribute(
s.Printf("[%s", DW_FORM_value_to_name(form_value.Form()));
}
- if (!form_value.ExtractValue(debug_info_data, offset_ptr))
+ if (!form_value.ExtractValue(data, offset_ptr))
return;
if (show_form) {
@@ -704,6 +481,8 @@ void DWARFDebugInfoEntry::DumpAttribute(
s.PutCString("( ");
+ SymbolFileDWARF &dwarf = cu->GetSymbolFileDWARF();
+
// Check to see if we have any special attribute formatters
switch (attr) {
case DW_AT_stmt_list:
@@ -724,7 +503,7 @@ void DWARFDebugInfoEntry::DumpAttribute(
const uint8_t *blockData = form_value.BlockData();
if (blockData) {
// Location description is inlined in data in the form value
- DWARFDataExtractor locationData(debug_info_data,
+ DWARFDataExtractor locationData(data,
(*offset_ptr) - form_value.Unsigned(),
form_value.Unsigned());
DWARFExpression::PrintDWARFExpression(
@@ -733,38 +512,26 @@ void DWARFDebugInfoEntry::DumpAttribute(
// We have a location list offset as the value that is the offset into
// the .debug_loc section that describes the value over it's lifetime
uint64_t debug_loc_offset = form_value.Unsigned();
- if (dwarf2Data) {
- DWARFExpression::PrintDWARFLocationList(
- s, cu, dwarf2Data->DebugLocData(), debug_loc_offset);
- }
+ DWARFExpression::PrintDWARFLocationList(s, cu, dwarf.DebugLocData(),
+ debug_loc_offset);
}
} break;
case DW_AT_abstract_origin:
case DW_AT_specification: {
- uint64_t abstract_die_offset = form_value.Reference();
+ DWARFDIE abstract_die = form_value.Reference();
form_value.Dump(s);
- // *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
- GetName(dwarf2Data, cu, abstract_die_offset, s);
+ // *ostrm_ptr << HEX32 << abstract_die.GetOffset() << " ( ";
+ abstract_die.GetName(s);
} break;
case DW_AT_type: {
- uint64_t type_die_offset = form_value.Reference();
+ DWARFDIE type_die = form_value.Reference();
s.PutCString(" ( ");
- AppendTypeName(dwarf2Data, cu, type_die_offset, s);
+ type_die.AppendTypeName(s);
s.PutCString(" )");
} break;
- case DW_AT_ranges: {
- if (!dwarf2Data)
- break;
- lldb::offset_t ranges_offset =
- GetRangesOffset(dwarf2Data->DebugRanges(), form_value);
- dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
- DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(),
- &ranges_offset, base_addr);
- } break;
-
default:
break;
}
@@ -772,36 +539,17 @@ void DWARFDebugInfoEntry::DumpAttribute(
s.PutCString(" )\n");
}
-//----------------------------------------------------------------------
// Get all attribute values for a given DIE, including following any
// specification or abstract origin attributes and including those in the
// results. Any duplicate attributes will have the first instance take
// precedence (this can happen for declaration attributes).
-//----------------------------------------------------------------------
size_t DWARFDebugInfoEntry::GetAttributes(
- const DWARFUnit *cu, DWARFFormValue::FixedFormSizes fixed_form_sizes,
- DWARFAttributes &attributes, uint32_t curr_depth) const {
- SymbolFileDWARF *dwarf2Data = nullptr;
- const DWARFAbbreviationDeclaration *abbrevDecl = nullptr;
- lldb::offset_t offset = 0;
- if (cu) {
- if (m_tag != DW_TAG_compile_unit && m_tag != DW_TAG_partial_unit) {
- SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
- if (dwo_symbol_file)
- return GetAttributes(dwo_symbol_file->GetCompileUnit(),
- fixed_form_sizes, attributes, curr_depth);
- }
-
- dwarf2Data = cu->GetSymbolFileDWARF();
- abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
- }
-
+ const DWARFUnit *cu, DWARFAttributes &attributes,
+ uint32_t curr_depth) const {
+ const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
if (abbrevDecl) {
- const DWARFDataExtractor &debug_info_data = cu->GetData();
-
- if (fixed_form_sizes.Empty())
- fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
- cu->GetAddressByteSize(), cu->IsDWARF64());
+ const DWARFDataExtractor &data = cu->GetData();
+ lldb::offset_t offset = GetFirstAttributeOffset();
const uint32_t num_attributes = abbrevDecl->NumAttributes();
for (uint32_t i = 0; i < num_attributes; ++i) {
@@ -829,19 +577,17 @@ size_t DWARFDebugInfoEntry::GetAttributes(
}
if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) {
- if (form_value.ExtractValue(debug_info_data, &offset)) {
- dw_offset_t die_offset = form_value.Reference();
- DWARFDIE spec_die =
- const_cast<DWARFUnit *>(cu)->GetDIE(die_offset);
+ if (form_value.ExtractValue(data, &offset)) {
+ DWARFDIE spec_die = form_value.Reference();
if (spec_die)
spec_die.GetAttributes(attributes, curr_depth + 1);
}
} else {
- const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
+ llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu);
if (fixed_skip_size)
- offset += fixed_skip_size;
+ offset += *fixed_skip_size;
else
- DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
+ DWARFFormValue::SkipValue(form, data, &offset, cu);
}
}
} else {
@@ -850,45 +596,32 @@ size_t DWARFDebugInfoEntry::GetAttributes(
return attributes.Size();
}
-//----------------------------------------------------------------------
// GetAttributeValue
//
-// Get the value of an attribute and return the .debug_info offset of the
-// attribute if it was properly extracted into form_value, or zero if we fail
-// since an offset of zero is invalid for an attribute (it would be a compile
-// unit header).
-//----------------------------------------------------------------------
+// Get the value of an attribute and return the .debug_info or .debug_types
+// offset of the attribute if it was properly extracted into form_value,
+// or zero if we fail since an offset of zero is invalid for an attribute (it
+// would be a compile unit header).
dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, DWARFFormValue &form_value,
+ const DWARFUnit *cu, const dw_attr_t attr, DWARFFormValue &form_value,
dw_offset_t *end_attr_offset_ptr,
bool check_specification_or_abstract_origin) const {
- SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
- if (dwo_symbol_file && m_tag != DW_TAG_compile_unit &&
- m_tag != DW_TAG_partial_unit)
- return GetAttributeValue(dwo_symbol_file, dwo_symbol_file->GetCompileUnit(),
- attr, form_value, end_attr_offset_ptr,
- check_specification_or_abstract_origin);
-
- lldb::offset_t offset;
- const DWARFAbbreviationDeclaration *abbrevDecl =
- GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
-
- if (abbrevDecl) {
+ if (const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu)) {
uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
if (attr_idx != DW_INVALID_INDEX) {
- const DWARFDataExtractor &debug_info_data = cu->GetData();
+ const DWARFDataExtractor &data = cu->GetData();
+ lldb::offset_t offset = GetFirstAttributeOffset();
uint32_t idx = 0;
while (idx < attr_idx)
DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++),
- debug_info_data, &offset, cu);
+ data, &offset, cu);
const dw_offset_t attr_offset = offset;
- form_value.SetCompileUnit(cu);
+ form_value.SetUnit(cu);
form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
- if (form_value.ExtractValue(debug_info_data, &offset)) {
+ if (form_value.ExtractValue(data, &offset)) {
if (end_attr_offset_ptr)
*end_attr_offset_ptr = offset;
return attr_offset;
@@ -897,35 +630,35 @@ dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
}
if (check_specification_or_abstract_origin) {
- if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) {
- DWARFDIE die =
- const_cast<DWARFUnit *>(cu)->GetDIE(form_value.Reference());
+ if (GetAttributeValue(cu, DW_AT_specification, form_value)) {
+ DWARFDIE die = form_value.Reference();
if (die) {
dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
- die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
- false);
+ die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
if (die_offset)
return die_offset;
}
}
- if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) {
- DWARFDIE die =
- const_cast<DWARFUnit *>(cu)->GetDIE(form_value.Reference());
+ if (GetAttributeValue(cu, DW_AT_abstract_origin, form_value)) {
+ DWARFDIE die = form_value.Reference();
if (die) {
dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
- die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
- false);
+ die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
if (die_offset)
return die_offset;
}
}
}
+ // If we're a unit DIE, also check the attributes of the dwo unit (if any).
+ if (GetParent())
+ return 0;
+ SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
if (!dwo_symbol_file)
return 0;
- DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
+ DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
if (!dwo_cu)
return 0;
@@ -934,105 +667,78 @@ dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
return 0;
return dwo_cu_die.GetDIE()->GetAttributeValue(
- dwo_symbol_file, dwo_cu, attr, form_value, end_attr_offset_ptr,
+ dwo_cu, attr, form_value, end_attr_offset_ptr,
check_specification_or_abstract_origin);
}
-//----------------------------------------------------------------------
// GetAttributeValueAsString
//
// Get the value of an attribute as a string return it. The resulting pointer
// to the string data exists within the supplied SymbolFileDWARF and will only
// be available as long as the SymbolFileDWARF is still around and it's content
// doesn't change.
-//----------------------------------------------------------------------
const char *DWARFDebugInfoEntry::GetAttributeValueAsString(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, const char *fail_value,
+ const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value,
bool check_specification_or_abstract_origin) const {
DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ if (GetAttributeValue(cu, attr, form_value, nullptr,
check_specification_or_abstract_origin))
return form_value.AsCString();
return fail_value;
}
-//----------------------------------------------------------------------
// GetAttributeValueAsUnsigned
//
// Get the value of an attribute as unsigned and return it.
-//----------------------------------------------------------------------
uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, uint64_t fail_value,
+ const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
bool check_specification_or_abstract_origin) const {
DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ if (GetAttributeValue(cu, attr, form_value, nullptr,
check_specification_or_abstract_origin))
return form_value.Unsigned();
return fail_value;
}
-//----------------------------------------------------------------------
-// GetAttributeValueAsSigned
-//
-// Get the value of an attribute a signed value and return it.
-//----------------------------------------------------------------------
-int64_t DWARFDebugInfoEntry::GetAttributeValueAsSigned(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, int64_t fail_value,
- bool check_specification_or_abstract_origin) const {
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
- check_specification_or_abstract_origin))
- return form_value.Signed();
- return fail_value;
-}
-
-//----------------------------------------------------------------------
// GetAttributeValueAsReference
//
// Get the value of an attribute as reference and fix up and compile unit
// relative offsets as needed.
-//----------------------------------------------------------------------
-uint64_t DWARFDebugInfoEntry::GetAttributeValueAsReference(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, uint64_t fail_value,
+DWARFDIE DWARFDebugInfoEntry::GetAttributeValueAsReference(
+ const DWARFUnit *cu, const dw_attr_t attr,
bool check_specification_or_abstract_origin) const {
DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ if (GetAttributeValue(cu, attr, form_value, nullptr,
check_specification_or_abstract_origin))
return form_value.Reference();
- return fail_value;
+ return {};
}
uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, uint64_t fail_value,
+ const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
bool check_specification_or_abstract_origin) const {
DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ if (GetAttributeValue(cu, attr, form_value, nullptr,
check_specification_or_abstract_origin))
return form_value.Address();
return fail_value;
}
-//----------------------------------------------------------------------
// GetAttributeHighPC
//
// Get the hi_pc, adding hi_pc to lo_pc when specified as an <offset-from-low-
// pc>.
//
// Returns the hi_pc or fail_value.
-//----------------------------------------------------------------------
dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, dw_addr_t lo_pc,
- uint64_t fail_value, bool check_specification_or_abstract_origin) const {
+ const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value,
+ bool check_specification_or_abstract_origin) const {
DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr,
+ if (GetAttributeValue(cu, DW_AT_high_pc, form_value, nullptr,
check_specification_or_abstract_origin)) {
dw_form_t form = form_value.Form();
- if (form == DW_FORM_addr || form == DW_FORM_GNU_addr_index)
+ if (form == DW_FORM_addr || form == DW_FORM_addrx ||
+ form == DW_FORM_GNU_addr_index)
return form_value.Address();
// DWARF4 can specify the hi_pc as an <offset-from-lowpc>
@@ -1041,22 +747,19 @@ dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
return fail_value;
}
-//----------------------------------------------------------------------
// GetAttributeAddressRange
//
// Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified as an <offset-
// from-low-pc>.
//
// Returns true or sets lo_pc and hi_pc to fail_value.
-//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::GetAttributeAddressRange(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, dw_addr_t &lo_pc,
- dw_addr_t &hi_pc, uint64_t fail_value,
- bool check_specification_or_abstract_origin) const {
- lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value,
+ const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc,
+ uint64_t fail_value, bool check_specification_or_abstract_origin) const {
+ lo_pc = GetAttributeValueAsAddress(cu, DW_AT_low_pc, fail_value,
check_specification_or_abstract_origin);
if (lo_pc != fail_value) {
- hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value,
+ hi_pc = GetAttributeHighPC(cu, lo_pc, fail_value,
check_specification_or_abstract_origin);
if (hi_pc != fail_value)
return true;
@@ -1067,21 +770,17 @@ bool DWARFDebugInfoEntry::GetAttributeAddressRange(
}
size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- DWARFRangeList &ranges, bool check_hi_lo_pc,
+ const DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc,
bool check_specification_or_abstract_origin) const {
ranges.Clear();
DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) {
- if (DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges())
- debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value),
- ranges);
+ if (GetAttributeValue(cu, DW_AT_ranges, form_value)) {
+ ranges = GetRangesOrReportError(*cu, *this, form_value);
} else if (check_hi_lo_pc) {
dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
- LLDB_INVALID_ADDRESS,
+ if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS,
check_specification_or_abstract_origin)) {
if (lo_pc < hi_pc)
ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
@@ -1090,250 +789,67 @@ size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
return ranges.GetSize();
}
-//----------------------------------------------------------------------
// GetName
//
// Get value of the DW_AT_name attribute and return it if one exists, else
// return NULL.
-//----------------------------------------------------------------------
-const char *DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu) const {
- return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+const char *DWARFDebugInfoEntry::GetName(const DWARFUnit *cu) const {
+ return GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
}
-//----------------------------------------------------------------------
// GetMangledName
//
// Get value of the DW_AT_MIPS_linkage_name attribute and return it if one
// exists, else return the value of the DW_AT_name attribute
-//----------------------------------------------------------------------
const char *
-DWARFDebugInfoEntry::GetMangledName(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu,
+DWARFDebugInfoEntry::GetMangledName(const DWARFUnit *cu,
bool substitute_name_allowed) const {
const char *name = nullptr;
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name,
- nullptr, true);
+ name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true);
if (name)
return name;
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr,
- true);
+ name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true);
if (name)
return name;
if (!substitute_name_allowed)
return nullptr;
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+ name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
return name;
}
-//----------------------------------------------------------------------
// GetPubname
//
// Get value the name for a DIE as it should appear for a .debug_pubnames or
// .debug_pubtypes section.
-//----------------------------------------------------------------------
-const char *DWARFDebugInfoEntry::GetPubname(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu) const {
+const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const {
const char *name = nullptr;
- if (!dwarf2Data)
+ if (!cu)
return name;
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name,
- nullptr, true);
+ name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true);
if (name)
return name;
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr,
- true);
+ name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true);
if (name)
return name;
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+ name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
return name;
}
-//----------------------------------------------------------------------
-// GetName
-//
-// Get value of the DW_AT_name attribute for a debug information entry that
-// exists at offset "die_offset" and place that value into the supplied stream
-// object. If the DIE is a NULL object "NULL" is placed into the stream, and if
-// no DW_AT_name attribute exists for the DIE then nothing is printed.
-//----------------------------------------------------------------------
-bool DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu,
- const dw_offset_t die_offset, Stream &s) {
- if (dwarf2Data == NULL) {
- s.PutCString("NULL");
- return false;
- }
-
- DWARFDebugInfoEntry die;
- lldb::offset_t offset = die_offset;
- if (die.Extract(dwarf2Data, cu, &offset)) {
- if (die.IsNULL()) {
- s.PutCString("NULL");
- return true;
- } else {
- const char *name = die.GetAttributeValueAsString(
- dwarf2Data, cu, DW_AT_name, nullptr, true);
- if (name) {
- s.PutCString(name);
- return true;
- }
- }
- }
- return false;
-}
-
-//----------------------------------------------------------------------
-// AppendTypeName
-//
-// Follows the type name definition down through all needed tags to end up with
-// a fully qualified type name and dump the results to the supplied stream.
-// This is used to show the name of types given a type identifier.
-//----------------------------------------------------------------------
-bool DWARFDebugInfoEntry::AppendTypeName(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu,
- const dw_offset_t die_offset,
- Stream &s) {
- if (dwarf2Data == NULL) {
- s.PutCString("NULL");
- return false;
- }
-
- DWARFDebugInfoEntry die;
- lldb::offset_t offset = die_offset;
- if (die.Extract(dwarf2Data, cu, &offset)) {
- if (die.IsNULL()) {
- s.PutCString("NULL");
- return true;
- } else {
- const char *name = die.GetPubname(dwarf2Data, cu);
- if (name)
- s.PutCString(name);
- else {
- bool result = true;
- const DWARFAbbreviationDeclaration *abbrevDecl =
- die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
-
- if (abbrevDecl == NULL)
- return false;
-
- switch (abbrevDecl->Tag()) {
- case DW_TAG_array_type:
- break; // print out a "[]" after printing the full type of the element
- // below
- case DW_TAG_base_type:
- s.PutCString("base ");
- break;
- case DW_TAG_class_type:
- s.PutCString("class ");
- break;
- case DW_TAG_const_type:
- s.PutCString("const ");
- break;
- case DW_TAG_enumeration_type:
- s.PutCString("enum ");
- break;
- case DW_TAG_file_type:
- s.PutCString("file ");
- break;
- case DW_TAG_interface_type:
- s.PutCString("interface ");
- break;
- case DW_TAG_packed_type:
- s.PutCString("packed ");
- break;
- case DW_TAG_pointer_type:
- break; // print out a '*' after printing the full type below
- case DW_TAG_ptr_to_member_type:
- break; // print out a '*' after printing the full type below
- case DW_TAG_reference_type:
- break; // print out a '&' after printing the full type below
- case DW_TAG_restrict_type:
- s.PutCString("restrict ");
- break;
- case DW_TAG_set_type:
- s.PutCString("set ");
- break;
- case DW_TAG_shared_type:
- s.PutCString("shared ");
- break;
- case DW_TAG_string_type:
- s.PutCString("string ");
- break;
- case DW_TAG_structure_type:
- s.PutCString("struct ");
- break;
- case DW_TAG_subrange_type:
- s.PutCString("subrange ");
- break;
- case DW_TAG_subroutine_type:
- s.PutCString("function ");
- break;
- case DW_TAG_thrown_type:
- s.PutCString("thrown ");
- break;
- case DW_TAG_union_type:
- s.PutCString("union ");
- break;
- case DW_TAG_unspecified_type:
- s.PutCString("unspecified ");
- break;
- case DW_TAG_volatile_type:
- s.PutCString("volatile ");
- break;
- default:
- return false;
- }
-
- // Follow the DW_AT_type if possible
- DWARFFormValue form_value;
- if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) {
- uint64_t next_die_offset = form_value.Reference();
- result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
- }
-
- switch (abbrevDecl->Tag()) {
- case DW_TAG_array_type:
- s.PutCString("[]");
- break;
- case DW_TAG_pointer_type:
- s.PutChar('*');
- break;
- case DW_TAG_ptr_to_member_type:
- s.PutChar('*');
- break;
- case DW_TAG_reference_type:
- s.PutChar('&');
- break;
- default:
- break;
- }
- return result;
- }
- }
- }
- return false;
-}
-
-//----------------------------------------------------------------------
// BuildAddressRangeTable
-//----------------------------------------------------------------------
void DWARFDebugInfoEntry::BuildAddressRangeTable(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- DWARFDebugAranges *debug_aranges) const {
+ const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
if (m_tag) {
if (m_tag == DW_TAG_subprogram) {
dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
- LLDB_INVALID_ADDRESS)) {
+ if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) {
/// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x -
/// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc);
@@ -1342,29 +858,25 @@ void DWARFDebugInfoEntry::BuildAddressRangeTable(
const DWARFDebugInfoEntry *child = GetFirstChild();
while (child) {
- child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
+ child->BuildAddressRangeTable(cu, debug_aranges);
child = child->GetSibling();
}
}
}
-//----------------------------------------------------------------------
// BuildFunctionAddressRangeTable
//
// This function is very similar to the BuildAddressRangeTable function except
// that the actual DIE offset for the function is placed in the table instead
// of the compile unit offset (which is the way the standard .debug_aranges
// section does it).
-//----------------------------------------------------------------------
void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- DWARFDebugAranges *debug_aranges) const {
+ const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
if (m_tag) {
if (m_tag == DW_TAG_subprogram) {
dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
- LLDB_INVALID_ADDRESS)) {
+ if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) {
// printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " -
// 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc);
@@ -1373,57 +885,37 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
const DWARFDebugInfoEntry *child = GetFirstChild();
while (child) {
- child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
+ child->BuildFunctionAddressRangeTable(cu, debug_aranges);
child = child->GetSibling();
}
}
}
-void DWARFDebugInfoEntry::GetDeclContextDIEs(
- DWARFUnit *cu, DWARFDIECollection &decl_context_dies) const {
-
- DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
- die.GetDeclContextDIEs(decl_context_dies);
-}
-
void DWARFDebugInfoEntry::GetDWARFDeclContext(
- SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
- DWARFDeclContext &dwarf_decl_ctx) const {
+ DWARFUnit *cu, DWARFDeclContext &dwarf_decl_ctx) const {
const dw_tag_t tag = Tag();
if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) {
- dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
- DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
+ dwarf_decl_ctx.AppendDeclContext(tag, GetName(cu));
+ DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu);
if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) {
if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit &&
parent_decl_ctx_die.Tag() != DW_TAG_partial_unit)
parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext(
- parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(),
- dwarf_decl_ctx);
+ parent_decl_ctx_die.GetCU(), dwarf_decl_ctx);
}
}
}
-bool DWARFDebugInfoEntry::MatchesDWARFDeclContext(
- SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
- const DWARFDeclContext &dwarf_decl_ctx) const {
-
- DWARFDeclContext this_dwarf_decl_ctx;
- GetDWARFDeclContext(dwarf2Data, cu, this_dwarf_decl_ctx);
- return this_dwarf_decl_ctx == dwarf_decl_ctx;
-}
-
DWARFDIE
-DWARFDebugInfoEntry::GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
- DWARFUnit *cu) const {
+DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const {
DWARFAttributes attributes;
- GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
- return GetParentDeclContextDIE(dwarf2Data, cu, attributes);
+ GetAttributes(cu, attributes);
+ return GetParentDeclContextDIE(cu, attributes);
}
DWARFDIE
DWARFDebugInfoEntry::GetParentDeclContextDIE(
- SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
- const DWARFAttributes &attributes) const {
+ DWARFUnit *cu, const DWARFAttributes &attributes) const {
DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
while (die) {
@@ -1445,28 +937,18 @@ DWARFDebugInfoEntry::GetParentDeclContextDIE(
}
}
- dw_offset_t die_offset;
-
- die_offset =
- attributes.FormValueAsUnsigned(DW_AT_specification, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET) {
- DWARFDIE spec_die = cu->GetDIE(die_offset);
- if (spec_die) {
- DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
- if (decl_ctx_die)
- return decl_ctx_die;
- }
+ DWARFDIE spec_die = attributes.FormValueAsReference(DW_AT_specification);
+ if (spec_die) {
+ DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
+ if (decl_ctx_die)
+ return decl_ctx_die;
}
- die_offset = attributes.FormValueAsUnsigned(DW_AT_abstract_origin,
- DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET) {
- DWARFDIE abs_die = cu->GetDIE(die_offset);
- if (abs_die) {
- DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
- if (decl_ctx_die)
- return decl_ctx_die;
- }
+ DWARFDIE abs_die = attributes.FormValueAsReference(DW_AT_abstract_origin);
+ if (abs_die) {
+ DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
+ if (decl_ctx_die)
+ return decl_ctx_die;
}
die = die.GetParent();
@@ -1474,22 +956,22 @@ DWARFDebugInfoEntry::GetParentDeclContextDIE(
return DWARFDIE();
}
-const char *DWARFDebugInfoEntry::GetQualifiedName(SymbolFileDWARF *dwarf2Data,
- DWARFUnit *cu,
+const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
std::string &storage) const {
DWARFAttributes attributes;
- GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
- return GetQualifiedName(dwarf2Data, cu, attributes, storage);
+ GetAttributes(cu, attributes);
+ return GetQualifiedName(cu, attributes, storage);
}
-const char *DWARFDebugInfoEntry::GetQualifiedName(
- SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
- const DWARFAttributes &attributes, std::string &storage) const {
+const char *
+DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
+ const DWARFAttributes &attributes,
+ std::string &storage) const {
- const char *name = GetName(dwarf2Data, cu);
+ const char *name = GetName(cu);
if (name) {
- DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
+ DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu);
storage.clear();
// TODO: change this to get the correct decl context parent....
while (parent_decl_ctx_die) {
@@ -1530,15 +1012,11 @@ const char *DWARFDebugInfoEntry::GetQualifiedName(
storage.append(name);
}
if (storage.empty())
- return NULL;
+ return nullptr;
return storage.c_str();
}
-//----------------------------------------------------------------------
-// LookupAddress
-//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
- SymbolFileDWARF *dwarf2Data,
const DWARFUnit *cu,
DWARFDebugInfoEntry **function_die,
DWARFDebugInfoEntry **block_die) {
@@ -1555,13 +1033,9 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
check_children = true;
break;
case DW_TAG_entry_point:
- break;
case DW_TAG_enumeration_type:
- break;
case DW_TAG_formal_parameter:
- break;
case DW_TAG_imported_declaration:
- break;
case DW_TAG_label:
break;
case DW_TAG_lexical_block:
@@ -1569,9 +1043,7 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
match_addr_range = true;
break;
case DW_TAG_member:
- break;
case DW_TAG_pointer_type:
- break;
case DW_TAG_reference_type:
break;
case DW_TAG_compile_unit:
@@ -1583,20 +1055,15 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
check_children = true;
break;
case DW_TAG_subroutine_type:
- break;
case DW_TAG_typedef:
- break;
case DW_TAG_union_type:
- break;
case DW_TAG_unspecified_parameters:
- break;
case DW_TAG_variant:
break;
case DW_TAG_common_block:
check_children = true;
break;
case DW_TAG_common_inclusion:
- break;
case DW_TAG_inheritance:
break;
case DW_TAG_inlined_subroutine:
@@ -1607,86 +1074,62 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
match_addr_range = true;
break;
case DW_TAG_ptr_to_member_type:
- break;
case DW_TAG_set_type:
- break;
case DW_TAG_subrange_type:
- break;
case DW_TAG_with_stmt:
- break;
case DW_TAG_access_declaration:
- break;
case DW_TAG_base_type:
break;
case DW_TAG_catch_block:
match_addr_range = true;
break;
case DW_TAG_const_type:
- break;
case DW_TAG_constant:
- break;
case DW_TAG_enumerator:
- break;
case DW_TAG_file_type:
- break;
case DW_TAG_friend:
- break;
case DW_TAG_namelist:
- break;
case DW_TAG_namelist_item:
- break;
case DW_TAG_packed_type:
break;
case DW_TAG_subprogram:
match_addr_range = true;
break;
case DW_TAG_template_type_parameter:
- break;
case DW_TAG_template_value_parameter:
- break;
case DW_TAG_GNU_template_parameter_pack:
- break;
case DW_TAG_thrown_type:
break;
case DW_TAG_try_block:
match_addr_range = true;
break;
case DW_TAG_variant_part:
- break;
case DW_TAG_variable:
- break;
case DW_TAG_volatile_type:
- break;
case DW_TAG_dwarf_procedure:
- break;
case DW_TAG_restrict_type:
- break;
case DW_TAG_interface_type:
break;
case DW_TAG_namespace:
check_children = true;
break;
case DW_TAG_imported_module:
- break;
case DW_TAG_unspecified_type:
break;
case DW_TAG_partial_unit:
match_addr_range = true;
break;
case DW_TAG_imported_unit:
- break;
case DW_TAG_shared_type:
- break;
default:
break;
}
if (match_addr_range) {
- dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc,
- LLDB_INVALID_ADDRESS);
+ dw_addr_t lo_pc =
+ GetAttributeValueAsAddress(cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
if (lo_pc != LLDB_INVALID_ADDRESS) {
- dw_addr_t hi_pc =
- GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS);
+ dw_addr_t hi_pc = GetAttributeHighPC(cu, lo_pc, LLDB_INVALID_ADDRESS);
if (hi_pc != LLDB_INVALID_ADDRESS) {
// printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ",
// m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
@@ -1696,13 +1139,14 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
switch (m_tag) {
case DW_TAG_compile_unit: // File
case DW_TAG_partial_unit: // File
- check_children = ((function_die != NULL) || (block_die != NULL));
+ check_children =
+ ((function_die != nullptr) || (block_die != nullptr));
break;
case DW_TAG_subprogram: // Function
if (function_die)
*function_die = this;
- check_children = (block_die != NULL);
+ check_children = (block_die != nullptr);
break;
case DW_TAG_inlined_subroutine: // Inlined Function
@@ -1722,48 +1166,43 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
// Compile units may not have a valid high/low pc when there
// are address gaps in subroutines so we must always search
// if there is no valid high and low PC.
- check_children = (m_tag == DW_TAG_compile_unit ||
- m_tag == DW_TAG_partial_unit) &&
- ((function_die != NULL) || (block_die != NULL));
+ check_children =
+ (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit) &&
+ ((function_die != nullptr) || (block_die != nullptr));
}
} else {
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) {
- DWARFRangeList ranges;
- DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges();
- debug_ranges->FindRanges(
- cu, GetRangesOffset(debug_ranges, form_value), ranges);
-
- if (ranges.FindEntryThatContains(address)) {
- found_address = true;
- // puts("***MATCH***");
- switch (m_tag) {
- case DW_TAG_compile_unit: // File
- case DW_TAG_partial_unit: // File
- check_children = ((function_die != NULL) || (block_die != NULL));
+ DWARFRangeList ranges;
+ if (GetAttributeAddressRanges(cu, ranges, /*check_hi_lo_pc*/ false) &&
+ ranges.FindEntryThatContains(address)) {
+ found_address = true;
+ // puts("***MATCH***");
+ switch (m_tag) {
+ case DW_TAG_compile_unit: // File
+ case DW_TAG_partial_unit: // File
+ check_children =
+ ((function_die != nullptr) || (block_die != nullptr));
break;
- case DW_TAG_subprogram: // Function
- if (function_die)
- *function_die = this;
- check_children = (block_die != NULL);
- break;
-
- case DW_TAG_inlined_subroutine: // Inlined Function
- case DW_TAG_lexical_block: // Block { } in code
- if (block_die) {
- *block_die = this;
- check_children = true;
- }
- break;
+ case DW_TAG_subprogram: // Function
+ if (function_die)
+ *function_die = this;
+ check_children = (block_die != nullptr);
+ break;
- default:
+ case DW_TAG_inlined_subroutine: // Inlined Function
+ case DW_TAG_lexical_block: // Block { } in code
+ if (block_die) {
+ *block_die = this;
check_children = true;
- break;
}
- } else {
- check_children = false;
+ break;
+
+ default:
+ check_children = true;
+ break;
}
+ } else {
+ check_children = false;
}
}
}
@@ -1772,8 +1211,7 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
// printf("checking children\n");
DWARFDebugInfoEntry *child = GetFirstChild();
while (child) {
- if (child->LookupAddress(address, dwarf2Data, cu, function_die,
- block_die))
+ if (child->LookupAddress(address, cu, function_die, block_die))
return true;
child = child->GetSibling();
}
@@ -1782,59 +1220,18 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
return found_address;
}
-const DWARFAbbreviationDeclaration *
-DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- lldb::offset_t &offset) const {
- if (dwarf2Data) {
- offset = GetOffset();
-
- const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
- if (abbrev_set) {
- const DWARFAbbreviationDeclaration *abbrev_decl =
- abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
- if (abbrev_decl) {
- // Make sure the abbreviation code still matches. If it doesn't and the
- // DWARF data was mmap'ed, the backing file might have been modified
- // which is bad news.
- const uint64_t abbrev_code = cu->GetData().GetULEB128(&offset);
-
- if (abbrev_decl->Code() == abbrev_code)
- return abbrev_decl;
-
- dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
- "0x%8.8x: the DWARF debug information has been modified (abbrev "
- "code was %u, and is now %u)",
- GetOffset(), (uint32_t)abbrev_decl->Code(), (uint32_t)abbrev_code);
- }
- }
- }
- offset = DW_INVALID_OFFSET;
- return NULL;
-}
-
-bool DWARFDebugInfoEntry::OffsetLessThan(const DWARFDebugInfoEntry &a,
- const DWARFDebugInfoEntry &b) {
- return a.GetOffset() < b.GetOffset();
+lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const {
+ return GetOffset() + llvm::getULEB128Size(m_abbr_idx);
}
-void DWARFDebugInfoEntry::DumpDIECollection(
- Stream &strm, DWARFDebugInfoEntry::collection &die_collection) {
- DWARFDebugInfoEntry::const_iterator pos;
- DWARFDebugInfoEntry::const_iterator end = die_collection.end();
- strm.PutCString("\noffset parent sibling child\n");
- strm.PutCString("-------- -------- -------- --------\n");
- for (pos = die_collection.begin(); pos != end; ++pos) {
- const DWARFDebugInfoEntry &die_ref = *pos;
- const DWARFDebugInfoEntry *p = die_ref.GetParent();
- const DWARFDebugInfoEntry *s = die_ref.GetSibling();
- const DWARFDebugInfoEntry *c = die_ref.GetFirstChild();
- strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n", die_ref.GetOffset(),
- p ? p->GetOffset() : 0, s ? s->GetOffset() : 0,
- c ? c->GetOffset() : 0, die_ref.Tag(),
- DW_TAG_value_to_name(die_ref.Tag()),
- die_ref.HasChildren() ? " *" : "");
+const DWARFAbbreviationDeclaration *
+DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const {
+ if (cu) {
+ const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
+ if (abbrev_set)
+ return abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
}
+ return nullptr;
}
bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const {
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index ec19fc814fba..1e7b5f27642d 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -1,9 +1,8 @@
//===-- DWARFDebugInfoEntry.h -----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -20,26 +19,6 @@
#include <set>
#include <vector>
-typedef std::map<const DWARFDebugInfoEntry *, dw_addr_t> DIEToAddressMap;
-typedef DIEToAddressMap::iterator DIEToAddressMapIter;
-typedef DIEToAddressMap::const_iterator DIEToAddressMapConstIter;
-
-typedef std::map<dw_addr_t, const DWARFDebugInfoEntry *> AddressToDIEMap;
-typedef AddressToDIEMap::iterator AddressToDIEMapIter;
-typedef AddressToDIEMap::const_iterator AddressToDIEMapConstIter;
-
-typedef std::map<dw_offset_t, dw_offset_t> DIEToDIEMap;
-typedef DIEToDIEMap::iterator DIEToDIEMapIter;
-typedef DIEToDIEMap::const_iterator DIEToDIEMapConstIter;
-
-typedef std::map<uint32_t, const DWARFDebugInfoEntry *> UInt32ToDIEMap;
-typedef UInt32ToDIEMap::iterator UInt32ToDIEMapIter;
-typedef UInt32ToDIEMap::const_iterator UInt32ToDIEMapConstIter;
-
-typedef std::multimap<uint32_t, const DWARFDebugInfoEntry *> UInt32ToDIEMMap;
-typedef UInt32ToDIEMMap::iterator UInt32ToDIEMMapIter;
-typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter;
-
class DWARFDeclContext;
#define DIE_SIBLING_IDX_BITSIZE 31
@@ -50,10 +29,6 @@ public:
typedef collection::iterator iterator;
typedef collection::const_iterator const_iterator;
- typedef std::vector<dw_offset_t> offset_collection;
- typedef offset_collection::iterator offset_collection_iterator;
- typedef offset_collection::const_iterator offset_collection_const_iterator;
-
DWARFDebugInfoEntry()
: m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0),
m_has_children(false), m_abbr_idx(0), m_tag(0) {}
@@ -62,138 +37,90 @@ public:
bool operator==(const DWARFDebugInfoEntry &rhs) const;
bool operator!=(const DWARFDebugInfoEntry &rhs) const;
- void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu,
+ void BuildAddressRangeTable(const DWARFUnit *cu,
DWARFDebugAranges *debug_aranges) const;
- void BuildFunctionAddressRangeTable(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu,
+ void BuildFunctionAddressRangeTable(const DWARFUnit *cu,
DWARFDebugAranges *debug_aranges) const;
- bool FastExtract(const lldb_private::DWARFDataExtractor &debug_info_data,
- const DWARFUnit *cu,
- const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
- lldb::offset_t *offset_ptr);
+ bool Extract(const lldb_private::DWARFDataExtractor &data,
+ const DWARFUnit *cu, lldb::offset_t *offset_ptr);
- bool Extract(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- lldb::offset_t *offset_ptr);
-
- bool LookupAddress(const dw_addr_t address, SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu,
+ bool LookupAddress(const dw_addr_t address, const DWARFUnit *cu,
DWARFDebugInfoEntry **function_die,
DWARFDebugInfoEntry **block_die);
size_t GetAttributes(const DWARFUnit *cu,
- DWARFFormValue::FixedFormSizes fixed_form_sizes,
DWARFAttributes &attrs,
uint32_t curr_depth = 0)
const; // "curr_depth" for internal use only, don't set this yourself!!!
dw_offset_t
- GetAttributeValue(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, DWARFFormValue &formValue,
+ GetAttributeValue(const DWARFUnit *cu, const dw_attr_t attr,
+ DWARFFormValue &formValue,
dw_offset_t *end_attr_offset_ptr = nullptr,
bool check_specification_or_abstract_origin = false) const;
const char *GetAttributeValueAsString(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, const char *fail_value,
+ const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value,
bool check_specification_or_abstract_origin = false) const;
uint64_t GetAttributeValueAsUnsigned(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, uint64_t fail_value,
- bool check_specification_or_abstract_origin = false) const;
-
- uint64_t GetAttributeValueAsReference(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, uint64_t fail_value,
+ const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
bool check_specification_or_abstract_origin = false) const;
- int64_t GetAttributeValueAsSigned(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, int64_t fail_value,
+ DWARFDIE GetAttributeValueAsReference(
+ const DWARFUnit *cu, const dw_attr_t attr,
bool check_specification_or_abstract_origin = false) const;
uint64_t GetAttributeValueAsAddress(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, uint64_t fail_value,
+ const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
bool check_specification_or_abstract_origin = false) const;
dw_addr_t
- GetAttributeHighPC(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- dw_addr_t lo_pc, uint64_t fail_value,
+ GetAttributeHighPC(const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value,
bool check_specification_or_abstract_origin = false) const;
bool GetAttributeAddressRange(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, dw_addr_t &lo_pc,
- dw_addr_t &hi_pc, uint64_t fail_value,
+ const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc,
+ uint64_t fail_value,
bool check_specification_or_abstract_origin = false) const;
size_t GetAttributeAddressRanges(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- DWARFRangeList &ranges, bool check_hi_lo_pc,
+ const DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc,
bool check_specification_or_abstract_origin = false) const;
- const char *GetName(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu) const;
+ const char *GetName(const DWARFUnit *cu) const;
- const char *GetMangledName(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu,
+ const char *GetMangledName(const DWARFUnit *cu,
bool substitute_name_allowed = true) const;
- const char *GetPubname(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu) const;
+ const char *GetPubname(const DWARFUnit *cu) const;
- static bool GetName(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_offset_t die_offset, lldb_private::Stream &s);
-
- static bool AppendTypeName(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu,
- const dw_offset_t die_offset,
- lldb_private::Stream &s);
-
- const char *GetQualifiedName(SymbolFileDWARF *dwarf2Data,
- DWARFUnit *cu,
- std::string &storage) const;
+ const char *GetQualifiedName(DWARFUnit *cu, std::string &storage) const;
- const char *GetQualifiedName(SymbolFileDWARF *dwarf2Data,
- DWARFUnit *cu,
- const DWARFAttributes &attributes,
+ const char *GetQualifiedName(DWARFUnit *cu, const DWARFAttributes &attributes,
std::string &storage) const;
- static bool OffsetLessThan(const DWARFDebugInfoEntry &a,
- const DWARFDebugInfoEntry &b);
-
- void Dump(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- lldb_private::Stream &s, uint32_t recurse_depth) const;
-
- void DumpAncestry(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const DWARFDebugInfoEntry *oldest, lldb_private::Stream &s,
- uint32_t recurse_depth) const;
+ void Dump(const DWARFUnit *cu, lldb_private::Stream &s,
+ uint32_t recurse_depth) const;
static void
- DumpAttribute(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const lldb_private::DWARFDataExtractor &debug_info_data,
+ DumpAttribute(const DWARFUnit *cu,
+ const lldb_private::DWARFDataExtractor &data,
lldb::offset_t *offset_ptr, lldb_private::Stream &s,
dw_attr_t attr, DWARFFormValue &form_value);
- // This one dumps the comp unit name, objfile name and die offset for this die
- // so the stream S.
- void DumpLocation(SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
- lldb_private::Stream &s) const;
-
- bool
- GetDIENamesAndRanges(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const char *&name, const char *&mangled,
- DWARFRangeList &rangeList, int &decl_file,
- int &decl_line, int &decl_column, int &call_file,
- int &call_line, int &call_column,
- lldb_private::DWARFExpression *frame_base = NULL) const;
+
+ bool GetDIENamesAndRanges(
+ const DWARFUnit *cu, const char *&name, const char *&mangled,
+ DWARFRangeList &rangeList, int &decl_file, int &decl_line,
+ int &decl_column, int &call_file, int &call_line, int &call_column,
+ lldb_private::DWARFExpression *frame_base = nullptr) const;
const DWARFAbbreviationDeclaration *
- GetAbbreviationDeclarationPtr(SymbolFileDWARF *dwarf2Data,
- const DWARFUnit *cu,
- lldb::offset_t &offset) const;
+ GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const;
+
+ lldb::offset_t GetFirstAttributeOffset() const;
dw_tag_t Tag() const { return m_tag; }
@@ -208,74 +135,41 @@ public:
// We know we are kept in a vector of contiguous entries, so we know
// our parent will be some index behind "this".
DWARFDebugInfoEntry *GetParent() {
- return m_parent_idx > 0 ? this - m_parent_idx : NULL;
+ return m_parent_idx > 0 ? this - m_parent_idx : nullptr;
}
const DWARFDebugInfoEntry *GetParent() const {
- return m_parent_idx > 0 ? this - m_parent_idx : NULL;
+ return m_parent_idx > 0 ? this - m_parent_idx : nullptr;
}
// We know we are kept in a vector of contiguous entries, so we know
// our sibling will be some index after "this".
DWARFDebugInfoEntry *GetSibling() {
- return m_sibling_idx > 0 ? this + m_sibling_idx : NULL;
+ return m_sibling_idx > 0 ? this + m_sibling_idx : nullptr;
}
const DWARFDebugInfoEntry *GetSibling() const {
- return m_sibling_idx > 0 ? this + m_sibling_idx : NULL;
+ return m_sibling_idx > 0 ? this + m_sibling_idx : nullptr;
}
// We know we are kept in a vector of contiguous entries, so we know
// we don't need to store our child pointer, if we have a child it will
// be the next entry in the list...
DWARFDebugInfoEntry *GetFirstChild() {
- return HasChildren() ? this + 1 : NULL;
+ return HasChildren() ? this + 1 : nullptr;
}
const DWARFDebugInfoEntry *GetFirstChild() const {
- return HasChildren() ? this + 1 : NULL;
+ return HasChildren() ? this + 1 : nullptr;
}
- void GetDeclContextDIEs(DWARFUnit *cu,
- DWARFDIECollection &decl_context_dies) const;
-
- void GetDWARFDeclContext(SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
+ void GetDWARFDeclContext(DWARFUnit *cu,
DWARFDeclContext &dwarf_decl_ctx) const;
- bool MatchesDWARFDeclContext(SymbolFileDWARF *dwarf2Data,
- DWARFUnit *cu,
- const DWARFDeclContext &dwarf_decl_ctx) const;
-
- DWARFDIE GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
- DWARFUnit *cu) const;
- DWARFDIE GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
- DWARFUnit *cu,
+ DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu) const;
+ DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu,
const DWARFAttributes &attributes) const;
- void SetParent(DWARFDebugInfoEntry *parent) {
- if (parent) {
- // We know we are kept in a vector of contiguous entries, so we know
- // our parent will be some index behind "this".
- m_parent_idx = this - parent;
- } else
- m_parent_idx = 0;
- }
- void SetSibling(DWARFDebugInfoEntry *sibling) {
- if (sibling) {
- // We know we are kept in a vector of contiguous entries, so we know
- // our sibling will be some index after "this".
- m_sibling_idx = sibling - this;
- sibling->SetParent(GetParent());
- } else
- m_sibling_idx = 0;
- }
-
void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; }
-
void SetParentIndex(uint32_t idx) { m_parent_idx = idx; }
- static void
- DumpDIECollection(lldb_private::Stream &strm,
- DWARFDebugInfoEntry::collection &die_collection);
-
protected:
- dw_offset_t
- m_offset; // Offset within the .debug_info of the start of this entry
+ dw_offset_t m_offset; // Offset within the .debug_info/.debug_types
uint32_t m_parent_idx; // How many to subtract from "this" to get the parent.
// If zero this die has no parent
uint32_t m_sibling_idx : 31, // How many to add to "this" to get the sibling.
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
index d9f50122bd6f..953089fee22b 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
@@ -1,9 +1,8 @@
//===-- DWARFDebugLine.cpp --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -12,12 +11,15 @@
//#define ENABLE_DEBUG_PRINTF // DO NOT LEAVE THIS DEFINED: DEBUG ONLY!!!
#include <assert.h>
+#include <memory>
+
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Module.h"
#include "lldb/Host/Host.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Timer.h"
+#include "DWARFUnit.h"
#include "LogChannelDWARF.h"
#include "SymbolFileDWARF.h"
@@ -25,12 +27,10 @@ using namespace lldb;
using namespace lldb_private;
using namespace std;
-//----------------------------------------------------------------------
// Parse
//
// Parse all information in the debug_line_data into an internal
// representation.
-//----------------------------------------------------------------------
void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) {
m_lineTableMap.clear();
lldb::offset_t offset = 0;
@@ -38,7 +38,7 @@ void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) {
while (debug_line_data.ValidOffset(offset)) {
const lldb::offset_t debug_line_offset = offset;
- if (line_table_sp.get() == NULL)
+ if (line_table_sp.get() == nullptr)
break;
if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get(), nullptr)) {
@@ -48,7 +48,7 @@ void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) {
// DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n",
// debug_line_offset);
m_lineTableMap[debug_line_offset] = line_table_sp;
- line_table_sp.reset(new LineTable);
+ line_table_sp = std::make_shared<LineTable>();
} else
++offset; // Try next byte in line table
}
@@ -59,9 +59,7 @@ void DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor &debug_line_data) {
Parse(debug_line_data);
}
-//----------------------------------------------------------------------
// DWARFDebugLine::GetLineTable
-//----------------------------------------------------------------------
DWARFDebugLine::LineTable::shared_ptr
DWARFDebugLine::GetLineTable(const dw_offset_t offset) const {
DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr;
@@ -71,296 +69,11 @@ DWARFDebugLine::GetLineTable(const dw_offset_t offset) const {
return line_table_shared_ptr;
}
-//----------------------------------------------------------------------
-// DumpStateToFile
-//----------------------------------------------------------------------
-static void DumpStateToFile(dw_offset_t offset,
- const DWARFDebugLine::State &state,
- void *userData) {
- Log *log = (Log *)userData;
- if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
- // If the row is zero we are being called with the prologue only
- state.prologue->Dump(log);
- log->PutCString("Address Line Column File");
- log->PutCString("------------------ ------ ------ ------");
- } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
- // Done parsing line table
- } else {
- log->Printf("0x%16.16" PRIx64 " %6u %6u %6u%s\n", state.address, state.line,
- state.column, state.file, state.end_sequence ? " END" : "");
- }
-}
-
-//----------------------------------------------------------------------
-// DWARFDebugLine::DumpLineTableRows
-//----------------------------------------------------------------------
-bool DWARFDebugLine::DumpLineTableRows(Log *log, SymbolFileDWARF *dwarf2Data,
- dw_offset_t debug_line_offset) {
- const DWARFDataExtractor &debug_line_data = dwarf2Data->get_debug_line_data();
-
- if (debug_line_offset == DW_INVALID_OFFSET) {
- // Dump line table to a single file only
- debug_line_offset = 0;
- while (debug_line_data.ValidOffset(debug_line_offset))
- debug_line_offset =
- DumpStatementTable(log, debug_line_data, debug_line_offset);
- } else {
- // Dump line table to a single file only
- DumpStatementTable(log, debug_line_data, debug_line_offset);
- }
- return false;
-}
-
-//----------------------------------------------------------------------
-// DWARFDebugLine::DumpStatementTable
-//----------------------------------------------------------------------
-dw_offset_t
-DWARFDebugLine::DumpStatementTable(Log *log,
- const DWARFDataExtractor &debug_line_data,
- const dw_offset_t debug_line_offset) {
- if (debug_line_data.ValidOffset(debug_line_offset)) {
- lldb::offset_t offset = debug_line_offset;
- log->Printf("--------------------------------------------------------------"
- "--------\n"
- "debug_line[0x%8.8x]\n"
- "--------------------------------------------------------------"
- "--------\n",
- debug_line_offset);
-
- if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log, nullptr))
- return offset;
- else
- return debug_line_offset + 1; // Skip to next byte in .debug_line section
- }
-
- return DW_INVALID_OFFSET;
-}
-
-//----------------------------------------------------------------------
-// DumpOpcodes
-//----------------------------------------------------------------------
-bool DWARFDebugLine::DumpOpcodes(Log *log, SymbolFileDWARF *dwarf2Data,
- dw_offset_t debug_line_offset,
- uint32_t dump_flags) {
- const DWARFDataExtractor &debug_line_data = dwarf2Data->get_debug_line_data();
-
- if (debug_line_data.GetByteSize() == 0) {
- log->Printf("< EMPTY >\n");
- return false;
- }
-
- if (debug_line_offset == DW_INVALID_OFFSET) {
- // Dump line table to a single file only
- debug_line_offset = 0;
- while (debug_line_data.ValidOffset(debug_line_offset))
- debug_line_offset = DumpStatementOpcodes(log, debug_line_data,
- debug_line_offset, dump_flags);
- } else {
- // Dump line table to a single file only
- DumpStatementOpcodes(log, debug_line_data, debug_line_offset, dump_flags);
- }
- return false;
-}
-
-//----------------------------------------------------------------------
-// DumpStatementOpcodes
-//----------------------------------------------------------------------
-dw_offset_t DWARFDebugLine::DumpStatementOpcodes(
- Log *log, const DWARFDataExtractor &debug_line_data,
- const dw_offset_t debug_line_offset, uint32_t flags) {
- lldb::offset_t offset = debug_line_offset;
- if (debug_line_data.ValidOffset(offset)) {
- Prologue prologue;
-
- if (ParsePrologue(debug_line_data, &offset, &prologue)) {
- log->PutCString("--------------------------------------------------------"
- "--------------");
- log->Printf("debug_line[0x%8.8x]", debug_line_offset);
- log->PutCString("--------------------------------------------------------"
- "--------------\n");
- prologue.Dump(log);
- } else {
- offset = debug_line_offset;
- log->Printf("0x%8.8" PRIx64 ": skipping pad byte %2.2x", offset,
- debug_line_data.GetU8(&offset));
- return offset;
- }
-
- Row row(prologue.default_is_stmt);
- const dw_offset_t end_offset = debug_line_offset + prologue.total_length +
- sizeof(prologue.total_length);
-
- assert(debug_line_data.ValidOffset(end_offset - 1));
-
- while (offset < end_offset) {
- const uint32_t op_offset = offset;
- uint8_t opcode = debug_line_data.GetU8(&offset);
- switch (opcode) {
- case 0: // Extended Opcodes always start with a zero opcode followed by
- { // a uleb128 length so you can skip ones you don't know about
-
- dw_offset_t ext_offset = offset;
- dw_uleb128_t len = debug_line_data.GetULEB128(&offset);
- dw_offset_t arg_size = len - (offset - ext_offset);
- uint8_t sub_opcode = debug_line_data.GetU8(&offset);
- // if (verbose)
- // log->Printf( "Extended: <%u> %2.2x ", len,
- // sub_opcode);
-
- switch (sub_opcode) {
- case DW_LNE_end_sequence:
- log->Printf("0x%8.8x: DW_LNE_end_sequence", op_offset);
- row.Dump(log);
- row.Reset(prologue.default_is_stmt);
- break;
-
- case DW_LNE_set_address: {
- row.address = debug_line_data.GetMaxU64(&offset, arg_size);
- log->Printf("0x%8.8x: DW_LNE_set_address (0x%" PRIx64 ")", op_offset,
- row.address);
- } break;
-
- case DW_LNE_define_file: {
- FileNameEntry fileEntry;
- fileEntry.name = debug_line_data.GetCStr(&offset);
- fileEntry.dir_idx = debug_line_data.GetULEB128(&offset);
- fileEntry.mod_time = debug_line_data.GetULEB128(&offset);
- fileEntry.length = debug_line_data.GetULEB128(&offset);
- log->Printf("0x%8.8x: DW_LNE_define_file('%s', dir=%i, "
- "mod_time=0x%8.8x, length=%i )",
- op_offset, fileEntry.name, fileEntry.dir_idx,
- fileEntry.mod_time, fileEntry.length);
- prologue.file_names.push_back(fileEntry);
- } break;
-
- case DW_LNE_set_discriminator: {
- uint64_t discriminator = debug_line_data.GetULEB128(&offset);
- log->Printf("0x%8.8x: DW_LNE_set_discriminator (0x%" PRIx64 ")",
- op_offset, discriminator);
- } break;
- default:
- log->Printf("0x%8.8x: DW_LNE_??? (%2.2x) - Skipping unknown upcode",
- op_offset, opcode);
- // Length doesn't include the zero opcode byte or the length itself,
- // but it does include the sub_opcode, so we have to adjust for that
- // below
- offset += arg_size;
- break;
- }
- } break;
-
- // Standard Opcodes
- case DW_LNS_copy:
- log->Printf("0x%8.8x: DW_LNS_copy", op_offset);
- row.Dump(log);
- break;
-
- case DW_LNS_advance_pc: {
- dw_uleb128_t addr_offset_n = debug_line_data.GetULEB128(&offset);
- dw_uleb128_t addr_offset = addr_offset_n * prologue.min_inst_length;
- log->Printf("0x%8.8x: DW_LNS_advance_pc (0x%x)", op_offset,
- addr_offset);
- row.address += addr_offset;
- } break;
-
- case DW_LNS_advance_line: {
- dw_sleb128_t line_offset = debug_line_data.GetSLEB128(&offset);
- log->Printf("0x%8.8x: DW_LNS_advance_line (%i)", op_offset,
- line_offset);
- row.line += line_offset;
- } break;
-
- case DW_LNS_set_file:
- row.file = debug_line_data.GetULEB128(&offset);
- log->Printf("0x%8.8x: DW_LNS_set_file (%u)", op_offset, row.file);
- break;
-
- case DW_LNS_set_column:
- row.column = debug_line_data.GetULEB128(&offset);
- log->Printf("0x%8.8x: DW_LNS_set_column (%u)", op_offset, row.column);
- break;
-
- case DW_LNS_negate_stmt:
- row.is_stmt = !row.is_stmt;
- log->Printf("0x%8.8x: DW_LNS_negate_stmt", op_offset);
- break;
-
- case DW_LNS_set_basic_block:
- row.basic_block = true;
- log->Printf("0x%8.8x: DW_LNS_set_basic_block", op_offset);
- break;
-
- case DW_LNS_const_add_pc: {
- uint8_t adjust_opcode = 255 - prologue.opcode_base;
- dw_addr_t addr_offset =
- (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
- log->Printf("0x%8.8x: DW_LNS_const_add_pc (0x%8.8" PRIx64 ")",
- op_offset, addr_offset);
- row.address += addr_offset;
- } break;
-
- case DW_LNS_fixed_advance_pc: {
- uint16_t pc_offset = debug_line_data.GetU16(&offset);
- log->Printf("0x%8.8x: DW_LNS_fixed_advance_pc (0x%4.4x)", op_offset,
- pc_offset);
- row.address += pc_offset;
- } break;
-
- case DW_LNS_set_prologue_end:
- row.prologue_end = true;
- log->Printf("0x%8.8x: DW_LNS_set_prologue_end", op_offset);
- break;
-
- case DW_LNS_set_epilogue_begin:
- row.epilogue_begin = true;
- log->Printf("0x%8.8x: DW_LNS_set_epilogue_begin", op_offset);
- break;
-
- case DW_LNS_set_isa:
- row.isa = debug_line_data.GetULEB128(&offset);
- log->Printf("0x%8.8x: DW_LNS_set_isa (%u)", op_offset, row.isa);
- break;
-
- // Special Opcodes
- default:
- if (opcode < prologue.opcode_base) {
- // We have an opcode that this parser doesn't know about, skip the
- // number of ULEB128 numbers that is says to skip in the prologue's
- // standard_opcode_lengths array
- uint8_t n = prologue.standard_opcode_lengths[opcode - 1];
- log->Printf("0x%8.8x: Special : Unknown skipping %u ULEB128 values.",
- op_offset, n);
- while (n > 0) {
- debug_line_data.GetULEB128(&offset);
- --n;
- }
- } else {
- uint8_t adjust_opcode = opcode - prologue.opcode_base;
- dw_addr_t addr_offset =
- (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
- int32_t line_offset =
- prologue.line_base + (adjust_opcode % prologue.line_range);
- log->Printf("0x%8.8x: address += 0x%" PRIx64 ", line += %i\n",
- op_offset, (uint64_t)addr_offset, line_offset);
- row.address += addr_offset;
- row.line += line_offset;
- row.Dump(log);
- }
- break;
- }
- }
- return end_offset;
- }
- return DW_INVALID_OFFSET;
-}
-
-//----------------------------------------------------------------------
// Parse
//
// Parse the entire line table contents calling callback each time a new
// prologue is parsed and every time a new row is to be added to the line
// table.
-//----------------------------------------------------------------------
void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data,
DWARFDebugLine::State::Callback callback,
void *userData) {
@@ -392,9 +105,7 @@ ReadDescriptors(const DWARFDataExtractor &debug_line_data,
}
} // namespace
-//----------------------------------------------------------------------
// DWARFDebugLine::ParsePrologue
-//----------------------------------------------------------------------
bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
lldb::offset_t *offset_ptr,
Prologue *prologue, DWARFUnit *dwarf_cu) {
@@ -528,8 +239,7 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
bool DWARFDebugLine::ParseSupportFiles(
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, DWARFUnit *dwarf_cu) {
+ dw_offset_t stmt_list, FileSpecList &support_files, DWARFUnit *dwarf_cu) {
lldb::offset_t offset = stmt_list;
Prologue prologue;
@@ -545,7 +255,9 @@ bool DWARFDebugLine::ParseSupportFiles(
std::string remapped_file;
for (uint32_t file_idx = 1;
- prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx) {
+ prologue.GetFile(file_idx, dwarf_cu->GetCompilationDirectory(),
+ dwarf_cu->GetPathStyle(), file_spec);
+ ++file_idx) {
if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file))
file_spec.SetFile(remapped_file, FileSpec::Style::native);
support_files.Append(file_spec);
@@ -553,13 +265,11 @@ bool DWARFDebugLine::ParseSupportFiles(
return true;
}
-//----------------------------------------------------------------------
// ParseStatementTable
//
// Parse a single line table (prologue and all rows) and call the callback
// function once for the prologue (row in state will be zero) and each time a
// row is to be added to the line table.
-//----------------------------------------------------------------------
bool DWARFDebugLine::ParseStatementTable(
const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
DWARFDebugLine::State::Callback callback, void *userData, DWARFUnit *dwarf_cu) {
@@ -832,9 +542,7 @@ bool DWARFDebugLine::ParseStatementTable(
return end_offset;
}
-//----------------------------------------------------------------------
// ParseStatementTableCallback
-//----------------------------------------------------------------------
static void ParseStatementTableCallback(dw_offset_t offset,
const DWARFDebugLine::State &state,
void *userData) {
@@ -851,12 +559,10 @@ static void ParseStatementTableCallback(dw_offset_t offset,
}
}
-//----------------------------------------------------------------------
// ParseStatementTable
//
// Parse a line table at offset and populate the LineTable class with the
// prologue and all rows.
-//----------------------------------------------------------------------
bool DWARFDebugLine::ParseStatementTable(
const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
LineTable *line_table, DWARFUnit *dwarf_cu) {
@@ -868,9 +574,7 @@ inline bool DWARFDebugLine::Prologue::IsValid() const {
return SymbolFileDWARF::SupportedVersion(version);
}
-//----------------------------------------------------------------------
// DWARFDebugLine::Prologue::Dump
-//----------------------------------------------------------------------
void DWARFDebugLine::Prologue::Dump(Log *log) {
uint32_t i;
@@ -909,11 +613,9 @@ void DWARFDebugLine::Prologue::Dump(Log *log) {
}
}
-//----------------------------------------------------------------------
// DWARFDebugLine::ParsePrologue::Append
//
// Append the contents of the prologue to the binary stream buffer
-//----------------------------------------------------------------------
// void
// DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const
//{
@@ -947,10 +649,12 @@ void DWARFDebugLine::Prologue::Dump(Log *log) {
//}
bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx,
- const lldb_private::FileSpec &comp_dir, FileSpec &file) const {
+ const FileSpec &comp_dir,
+ FileSpec::Style style,
+ FileSpec &file) const {
uint32_t idx = file_idx - 1; // File indexes are 1 based...
if (idx < file_names.size()) {
- file.SetFile(file_names[idx].name, FileSpec::Style::native);
+ file.SetFile(file_names[idx].name, style);
if (file.IsRelative()) {
if (file_names[idx].dir_idx > 0) {
const uint32_t dir_idx = file_names[idx].dir_idx - 1;
@@ -969,42 +673,18 @@ bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx,
return false;
}
-//----------------------------------------------------------------------
-// DWARFDebugLine::LineTable::Dump
-//----------------------------------------------------------------------
-void DWARFDebugLine::LineTable::Dump(Log *log) const {
- if (prologue.get())
- prologue->Dump(log);
-
- if (!rows.empty()) {
- log->PutCString("Address Line Column File ISA Flags");
- log->PutCString(
- "------------------ ------ ------ ------ --- -------------");
- Row::const_iterator pos = rows.begin();
- Row::const_iterator end = rows.end();
- while (pos != end) {
- (*pos).Dump(log);
- ++pos;
- }
- }
-}
-
void DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row &state) {
rows.push_back(state);
}
-//----------------------------------------------------------------------
// Compare function for the binary search in
// DWARFDebugLine::LineTable::LookupAddress()
-//----------------------------------------------------------------------
static bool FindMatchingAddress(const DWARFDebugLine::Row &row1,
const DWARFDebugLine::Row &row2) {
return row1.address < row2.address;
}
-//----------------------------------------------------------------------
// DWARFDebugLine::LineTable::LookupAddress
-//----------------------------------------------------------------------
uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address,
dw_addr_t cu_high_pc) const {
uint32_t index = UINT32_MAX;
@@ -1037,26 +717,20 @@ uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address,
return index; // Failed to find address
}
-//----------------------------------------------------------------------
// DWARFDebugLine::Row::Row
-//----------------------------------------------------------------------
DWARFDebugLine::Row::Row(bool default_is_stmt)
: address(0), line(1), column(0), file(1), is_stmt(default_is_stmt),
basic_block(false), end_sequence(false), prologue_end(false),
epilogue_begin(false), isa(0) {}
-//----------------------------------------------------------------------
// Called after a row is appended to the matrix
-//----------------------------------------------------------------------
void DWARFDebugLine::Row::PostAppend() {
basic_block = false;
prologue_end = false;
epilogue_begin = false;
}
-//----------------------------------------------------------------------
// DWARFDebugLine::Row::Reset
-//----------------------------------------------------------------------
void DWARFDebugLine::Row::Reset(bool default_is_stmt) {
address = 0;
line = 1;
@@ -1069,9 +743,7 @@ void DWARFDebugLine::Row::Reset(bool default_is_stmt) {
epilogue_begin = false;
isa = 0;
}
-//----------------------------------------------------------------------
// DWARFDebugLine::Row::Dump
-//----------------------------------------------------------------------
void DWARFDebugLine::Row::Dump(Log *log) const {
log->Printf("0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s", address, line,
column, file, isa, is_stmt ? " is_stmt" : "",
@@ -1081,9 +753,7 @@ void DWARFDebugLine::Row::Dump(Log *log) const {
end_sequence ? " end_sequence" : "");
}
-//----------------------------------------------------------------------
// Compare function LineTable structures
-//----------------------------------------------------------------------
static bool AddressLessThan(const DWARFDebugLine::Row &a,
const DWARFDebugLine::Row &b) {
return a.address < b.address;
@@ -1123,14 +793,7 @@ void DWARFDebugLine::Row::Insert(Row::collection &state_coll,
}
}
-void DWARFDebugLine::Row::Dump(Log *log, const Row::collection &state_coll) {
- std::for_each(state_coll.begin(), state_coll.end(),
- bind2nd(std::mem_fun_ref(&Row::Dump), log));
-}
-
-//----------------------------------------------------------------------
// DWARFDebugLine::State::State
-//----------------------------------------------------------------------
DWARFDebugLine::State::State(Prologue::shared_ptr &p, Log *l,
DWARFDebugLine::State::Callback cb, void *userData)
: Row(p->default_is_stmt), prologue(p), log(l), callback(cb),
@@ -1140,14 +803,10 @@ DWARFDebugLine::State::State(Prologue::shared_ptr &p, Log *l,
callback(0, *this, callbackUserData);
}
-//----------------------------------------------------------------------
// DWARFDebugLine::State::Reset
-//----------------------------------------------------------------------
void DWARFDebugLine::State::Reset() { Row::Reset(prologue->default_is_stmt); }
-//----------------------------------------------------------------------
// DWARFDebugLine::State::AppendRowToMatrix
-//----------------------------------------------------------------------
void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) {
// Each time we are to add an entry into the line table matrix call the
// callback function so that someone can do something with the current state
@@ -1167,9 +826,7 @@ void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) {
PostAppend();
}
-//----------------------------------------------------------------------
// DWARFDebugLine::State::Finalize
-//----------------------------------------------------------------------
void DWARFDebugLine::State::Finalize(dw_offset_t offset) {
// Call the callback with a special row state when we are done parsing a line
// table
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
index 04f72e03a2db..0d236ca686b5 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
@@ -1,9 +1,8 @@
//===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -14,6 +13,7 @@
#include <string>
#include <vector>
+#include "lldb/Utility/FileSpec.h"
#include "lldb/lldb-private.h"
#include "DWARFDataExtractor.h"
@@ -24,16 +24,13 @@
class DWARFUnit;
class SymbolFileDWARF;
-//----------------------------------------------------------------------
// DWARFDebugLine
-//----------------------------------------------------------------------
class DWARFDebugLine {
public:
- //------------------------------------------------------------------
// FileNameEntry
- //------------------------------------------------------------------
struct FileNameEntry {
- FileNameEntry() : name(nullptr), dir_idx(0), mod_time(0), length(0) {}
+ FileNameEntry()
+ : name(nullptr), dir_idx(0), mod_time(0), length(0), checksum() {}
const char *name;
dw_sleb128_t dir_idx;
@@ -42,9 +39,7 @@ public:
llvm::MD5::MD5Result checksum;
};
- //------------------------------------------------------------------
// Prologue
- //------------------------------------------------------------------
struct Prologue {
Prologue()
@@ -99,6 +94,7 @@ public:
file_names.clear();
}
bool GetFile(uint32_t file_idx, const lldb_private::FileSpec &cu_comp_dir,
+ lldb_private::FileSpec::Style style,
lldb_private::FileSpec &file) const;
};
@@ -114,7 +110,6 @@ public:
void Reset(bool default_is_stmt);
void Dump(lldb_private::Log *log) const;
static void Insert(Row::collection &state_coll, const Row &state);
- static void Dump(lldb_private::Log *log, const Row::collection &state_coll);
dw_addr_t address; // The program-counter value corresponding to a machine
// instruction generated by the compiler.
@@ -145,9 +140,7 @@ public:
// instruction set architecture for the current instruction.
};
- //------------------------------------------------------------------
// LineTable
- //------------------------------------------------------------------
struct LineTable {
typedef std::shared_ptr<LineTable> shared_ptr;
@@ -160,15 +153,12 @@ public:
}
uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const;
- void Dump(lldb_private::Log *log) const;
Prologue::shared_ptr prologue;
Row::collection rows;
};
- //------------------------------------------------------------------
// State
- //------------------------------------------------------------------
struct State : public Row {
typedef void (*Callback)(dw_offset_t offset, const State &state,
void *userData);
@@ -196,20 +186,12 @@ public:
DISALLOW_COPY_AND_ASSIGN(State);
};
- static bool DumpOpcodes(
- lldb_private::Log *log, SymbolFileDWARF *dwarf2Data,
- dw_offset_t line_offset = DW_INVALID_OFFSET,
- uint32_t dump_flags = 0); // If line_offset is invalid, dump everything
- static bool DumpLineTableRows(
- lldb_private::Log *log, SymbolFileDWARF *dwarf2Data,
- dw_offset_t line_offset =
- DW_INVALID_OFFSET); // If line_offset is invalid, dump everything
static bool
ParseSupportFiles(const lldb::ModuleSP &module_sp,
const lldb_private::DWARFDataExtractor &debug_line_data,
- const lldb_private::FileSpec &cu_comp_dir,
dw_offset_t stmt_list,
- lldb_private::FileSpecList &support_files, DWARFUnit *dwarf_cu);
+ lldb_private::FileSpecList &support_files,
+ DWARFUnit *dwarf_cu);
static bool
ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
lldb::offset_t *offset_ptr, Prologue *prologue,
@@ -218,14 +200,6 @@ public:
ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
lldb::offset_t *offset_ptr, State::Callback callback,
void *userData, DWARFUnit *dwarf_cu);
- static dw_offset_t
- DumpStatementTable(lldb_private::Log *log,
- const lldb_private::DWARFDataExtractor &debug_line_data,
- const dw_offset_t line_offset);
- static dw_offset_t
- DumpStatementOpcodes(lldb_private::Log *log,
- const lldb_private::DWARFDataExtractor &debug_line_data,
- const dw_offset_t line_offset, uint32_t flags);
static bool
ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
lldb::offset_t *offset_ptr, LineTable *line_table,
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp
deleted file mode 100644
index 19074b8865ff..000000000000
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-//===-- DWARFDebugMacinfo.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DWARFDebugMacinfo.h"
-
-#include "DWARFDebugMacinfoEntry.h"
-#include "SymbolFileDWARF.h"
-
-#include "lldb/Utility/Stream.h"
-
-using namespace lldb_private;
-using namespace std;
-
-DWARFDebugMacinfo::DWARFDebugMacinfo() {}
-
-DWARFDebugMacinfo::~DWARFDebugMacinfo() {}
-
-void DWARFDebugMacinfo::Dump(Stream *s, const DWARFDataExtractor &macinfo_data,
- lldb::offset_t offset) {
- DWARFDebugMacinfoEntry maninfo_entry;
- if (macinfo_data.GetByteSize() == 0) {
- s->PutCString("< EMPTY >\n");
- return;
- }
- if (offset == LLDB_INVALID_OFFSET) {
- offset = 0;
- while (maninfo_entry.Extract(macinfo_data, &offset))
- maninfo_entry.Dump(s);
- } else {
- if (maninfo_entry.Extract(macinfo_data, &offset))
- maninfo_entry.Dump(s);
- }
-}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
deleted file mode 100644
index ec9dc85669c4..000000000000
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
+++ /dev/null
@@ -1,26 +0,0 @@
-//===-- DWARFDebugMacinfo.h -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SymbolFileDWARF_DWARFDebugMacinfo_h_
-#define SymbolFileDWARF_DWARFDebugMacinfo_h_
-
-#include "SymbolFileDWARF.h"
-
-class DWARFDebugMacinfo {
-public:
- DWARFDebugMacinfo();
-
- ~DWARFDebugMacinfo();
-
- static void Dump(lldb_private::Stream *s,
- const lldb_private::DWARFDataExtractor &macinfo_data,
- lldb::offset_t offset = LLDB_INVALID_OFFSET);
-};
-
-#endif // SymbolFileDWARF_DWARFDebugMacinfo_h_
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp
deleted file mode 100644
index f078fbd44f2f..000000000000
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-//===-- DWARFDebugMacinfoEntry.cpp ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DWARFDebugMacinfoEntry.h"
-
-#include "lldb/Utility/Stream.h"
-
-using namespace lldb_private;
-using namespace std;
-
-DWARFDebugMacinfoEntry::DWARFDebugMacinfoEntry()
- : m_type_code(0), m_line(0), m_op2() {
- m_op2.cstr = NULL;
-}
-
-DWARFDebugMacinfoEntry::~DWARFDebugMacinfoEntry() {}
-
-const char *DWARFDebugMacinfoEntry::GetCString() const {
- switch (m_type_code) {
- case 0:
- case DW_MACINFO_start_file:
- case DW_MACINFO_end_file:
- return NULL;
- default:
- break;
- }
- return m_op2.cstr;
-}
-
-void DWARFDebugMacinfoEntry::Dump(Stream *s) const {
- if (m_type_code) {
- s->PutCString(DW_MACINFO_value_to_name(m_type_code));
-
- switch (m_type_code) {
- case DW_MACINFO_define:
- s->Printf(" line:%u #define %s\n", (uint32_t)m_line, m_op2.cstr);
- break;
-
- case DW_MACINFO_undef:
- s->Printf(" line:%u #undef %s\n", (uint32_t)m_line, m_op2.cstr);
- break;
-
- default:
- s->Printf(" line:%u str: '%s'\n", (uint32_t)m_line, m_op2.cstr);
- break;
-
- case DW_MACINFO_start_file:
- s->Printf(" line:%u file index: '%u'\n", (uint32_t)m_line,
- (uint32_t)m_op2.file_idx);
- break;
-
- case DW_MACINFO_end_file:
- break;
- }
- } else {
- s->PutCString(" END\n");
- }
-}
-
-bool DWARFDebugMacinfoEntry::Extract(const DWARFDataExtractor &mac_info_data,
- lldb::offset_t *offset_ptr) {
- if (mac_info_data.ValidOffset(*offset_ptr)) {
- m_type_code = mac_info_data.GetU8(offset_ptr);
-
- switch (m_type_code) {
-
- case DW_MACINFO_define:
- case DW_MACINFO_undef:
- // 2 operands:
- // Arg 1: operand encodes the line number of the source line on which
- // the relevant defining or undefining pre-processor directives
- // appeared.
- m_line = mac_info_data.GetULEB128(offset_ptr);
- // Arg 2: define string
- m_op2.cstr = mac_info_data.GetCStr(offset_ptr);
- break;
-
- case DW_MACINFO_start_file:
- // 2 operands:
- // Op 1: line number of the source line on which the inclusion
- // pre-processor directive occurred.
- m_line = mac_info_data.GetULEB128(offset_ptr);
- // Op 2: a source file name index to a file number in the statement
- // information table for the relevant compilation unit.
- m_op2.file_idx = mac_info_data.GetULEB128(offset_ptr);
- break;
-
- case 0: // End of list
- case DW_MACINFO_end_file:
- // No operands
- m_line = DW_INVALID_OFFSET;
- m_op2.cstr = NULL;
- break;
- default:
- // Vendor specific entries always have a ULEB128 and a string
- m_line = mac_info_data.GetULEB128(offset_ptr);
- m_op2.cstr = mac_info_data.GetCStr(offset_ptr);
- break;
- }
- return true;
- } else
- m_type_code = 0;
-
- return false;
-}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h
deleted file mode 100644
index 96829c2fc09b..000000000000
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===-- DWARFDebugMacinfoEntry.h --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SymbolFileDWARF_DWARFDebugMacinfoEntry_h_
-#define SymbolFileDWARF_DWARFDebugMacinfoEntry_h_
-
-#include "SymbolFileDWARF.h"
-
-class DWARFDebugMacinfoEntry {
-public:
- DWARFDebugMacinfoEntry();
-
- ~DWARFDebugMacinfoEntry();
-
- uint8_t TypeCode() const { return m_type_code; }
-
- uint8_t GetLineNumber() const { return m_line; }
-
- void Dump(lldb_private::Stream *s) const;
-
- const char *GetCString() const;
-
- bool Extract(const lldb_private::DWARFDataExtractor &mac_info_data,
- lldb::offset_t *offset_ptr);
-
-protected:
-private:
- uint8_t m_type_code;
- dw_uleb128_t m_line;
- union {
- dw_uleb128_t file_idx;
- const char *cstr;
- } m_op2;
-};
-
-#endif // SymbolFileDWARF_DWARFDebugMacinfoEntry_h_
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
index d79acdc5cfc4..4238be7ec1c3 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
@@ -1,9 +1,8 @@
//===-- DWARFDebugMacro.cpp -------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
index 021b434cd457..c3a93a9f4d14 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
@@ -1,10 +1,9 @@
//===-- DWARFDebugMacro.h ----------------------------------------*- C++
//-*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index a0436dd7ffad..207c71211c9a 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -1,20 +1,16 @@
//===-- DWARFDebugRanges.cpp ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DWARFDebugRanges.h"
#include "DWARFUnit.h"
-#include "SymbolFileDWARF.h"
#include "lldb/Utility/Stream.h"
-#include <assert.h>
using namespace lldb_private;
-using namespace std;
static dw_addr_t GetBaseAddressMarker(uint32_t addr_size) {
switch(addr_size) {
@@ -30,25 +26,24 @@ static dw_addr_t GetBaseAddressMarker(uint32_t addr_size) {
DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}
-void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) {
+void DWARFDebugRanges::Extract(DWARFContext &context) {
DWARFRangeList range_list;
lldb::offset_t offset = 0;
dw_offset_t debug_ranges_offset = offset;
- while (Extract(dwarf2Data, &offset, range_list)) {
+ while (Extract(context, &offset, range_list)) {
range_list.Sort();
m_range_map[debug_ranges_offset] = range_list;
debug_ranges_offset = offset;
}
}
-bool DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data,
+bool DWARFDebugRanges::Extract(DWARFContext &context,
lldb::offset_t *offset_ptr,
DWARFRangeList &range_list) {
range_list.Clear();
lldb::offset_t range_offset = *offset_ptr;
- const DWARFDataExtractor &debug_ranges_data =
- dwarf2Data->get_debug_ranges_data();
+ const DWARFDataExtractor &debug_ranges_data = context.getOrLoadRangesData();
uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
dw_addr_t base_addr = 0;
dw_addr_t base_addr_marker = GetBaseAddressMarker(addr_size);
@@ -106,7 +101,7 @@ void DWARFDebugRanges::Dump(Stream &s,
dw_addr_t begin_addr = begin + base_addr;
dw_addr_t end_addr = end + base_addr;
- s.AddressRange(begin_addr, end_addr, sizeof(dw_addr_t), NULL);
+ s.AddressRange(begin_addr, end_addr, sizeof(dw_addr_t), nullptr);
}
}
}
@@ -205,8 +200,10 @@ static uint64_t ReadAddressFromDebugAddrSection(const DWARFUnit *cu,
uint32_t index_size = cu->GetAddressByteSize();
dw_offset_t addr_base = cu->GetAddrBase();
lldb::offset_t offset = addr_base + index * index_size;
- return cu->GetSymbolFileDWARF()->get_debug_addr_data().GetMaxU64(&offset,
- index_size);
+ return cu->GetSymbolFileDWARF()
+ .GetDWARFContext()
+ .getOrLoadAddrData()
+ .GetMaxU64(&offset, index_size);
}
bool DWARFDebugRngLists::FindRanges(const DWARFUnit *cu,
@@ -256,14 +253,12 @@ bool DWARFDebugRngLists::FindRanges(const DWARFUnit *cu,
return false;
}
-void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) {
- const DWARFDataExtractor &data = dwarf2Data->get_debug_rnglists_data();
+void DWARFDebugRngLists::Extract(DWARFContext &context) {
+ const DWARFDataExtractor &data = context.getOrLoadRngListsData();
lldb::offset_t offset = 0;
uint64_t length = data.GetU32(&offset);
- bool isDwarf64 = (length == 0xffffffff);
- if (isDwarf64)
- length = data.GetU64(&offset);
+ // FIXME: Handle DWARF64.
lldb::offset_t end = offset + length;
// Check version.
@@ -280,7 +275,7 @@ void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) {
uint32_t offsetsAmount = data.GetU32(&offset);
for (uint32_t i = 0; i < offsetsAmount; ++i)
- Offsets.push_back(data.GetMaxU64(&offset, isDwarf64 ? 8 : 4));
+ Offsets.push_back(data.GetMaxU64(&offset, 4));
lldb::offset_t listOffset = offset;
std::vector<RngListEntry> rangeList;
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
index 5790f448ba85..baf2667f0afe 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -1,25 +1,27 @@
//===-- DWARFDebugRanges.h --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef SymbolFileDWARF_DWARFDebugRanges_h_
#define SymbolFileDWARF_DWARFDebugRanges_h_
-#include "DWARFDIE.h"
-#include "SymbolFileDWARF.h"
-
+#include "lldb/Core/dwarf.h"
#include <map>
+class DWARFUnit;
+namespace lldb_private {
+class DWARFContext;
+}
+
class DWARFDebugRangesBase {
public:
virtual ~DWARFDebugRangesBase(){};
- virtual void Extract(SymbolFileDWARF *dwarf2Data) = 0;
+ virtual void Extract(lldb_private::DWARFContext &context) = 0;
virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const = 0;
virtual uint64_t GetOffset(size_t Index) const = 0;
@@ -29,7 +31,7 @@ class DWARFDebugRanges final : public DWARFDebugRangesBase {
public:
DWARFDebugRanges();
- void Extract(SymbolFileDWARF *dwarf2Data) override;
+ void Extract(lldb_private::DWARFContext &context) override;
bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const override;
uint64_t GetOffset(size_t Index) const override;
@@ -39,7 +41,7 @@ public:
lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr);
protected:
- bool Extract(SymbolFileDWARF *dwarf2Data, lldb::offset_t *offset_ptr,
+ bool Extract(lldb_private::DWARFContext &context, lldb::offset_t *offset_ptr,
DWARFRangeList &range_list);
typedef std::map<dw_offset_t, DWARFRangeList> range_map;
@@ -57,7 +59,7 @@ class DWARFDebugRngLists final : public DWARFDebugRangesBase {
};
public:
- void Extract(SymbolFileDWARF *dwarf2Data) override;
+ void Extract(lldb_private::DWARFContext &context) override;
bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const override;
uint64_t GetOffset(size_t Index) const override;
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
index dbaf0b0ed127..a664314035e4 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
@@ -1,9 +1,8 @@
//===-- DWARFDeclContext.cpp ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -30,7 +29,7 @@ const char *DWARFDeclContext::GetQualifiedName() const {
for (pos = begin; pos != end; ++pos) {
if (pos != begin)
m_qualified_name.append("::");
- if (pos->name == NULL) {
+ if (pos->name == nullptr) {
if (pos->tag == DW_TAG_namespace)
m_qualified_name.append("(anonymous namespace)");
else if (pos->tag == DW_TAG_class_type)
@@ -48,7 +47,7 @@ const char *DWARFDeclContext::GetQualifiedName() const {
}
}
if (m_qualified_name.empty())
- return NULL;
+ return nullptr;
return m_qualified_name.c_str();
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index aff5ea64e9ce..d0d70dd5123e 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -1,9 +1,8 @@
//===-- DWARFDeclContext.h --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -15,18 +14,16 @@
#include "lldb/Utility/ConstString.h"
#include "DWARFDefines.h"
-//----------------------------------------------------------------------
// DWARFDeclContext
//
// A class that represents a declaration context all the way down to a
// DIE. This is useful when trying to find a DIE in one DWARF to a DIE
// in another DWARF file.
-//----------------------------------------------------------------------
class DWARFDeclContext {
public:
struct Entry {
- Entry() : tag(0), name(NULL) {}
+ Entry() : tag(0), name(nullptr) {}
Entry(dw_tag_t t, const char *n) : tag(t), name(n) {}
bool NameMatches(const Entry &rhs) const {
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
index 99becdbb2bc1..3bf0bb088227 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
@@ -1,9 +1,8 @@
//===-- DWARFDefines.cpp ----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -29,17 +28,6 @@ const char *DW_TAG_value_to_name(uint32_t val) {
return llvmstr.data();
}
-const char *DW_CHILDREN_value_to_name(uint8_t val) {
- static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::ChildrenString(val);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_CHILDREN constant: 0x%x",
- val);
- return invalid;
- }
- return llvmstr.data();
-}
-
const char *DW_AT_value_to_name(uint32_t val) {
static char invalid[100];
llvm::StringRef llvmstr = llvm::dwarf::AttributeString(val);
@@ -391,38 +379,6 @@ const char *DW_ATE_value_to_name(uint32_t val) {
return llvmstr.data();
}
-const char *DW_ACCESS_value_to_name(uint32_t val) {
- static char invalid[100];
-
- llvm::StringRef llvmstr = llvm::dwarf::AccessibilityString(val);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_ACCESS constant: 0x%x", val);
- return invalid;
- }
- return llvmstr.data();
-}
-
-const char *DW_VIS_value_to_name(uint32_t val) {
- static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::VisibilityString(val);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_VIS constant: 0x%x", val);
- return invalid;
- }
- return llvmstr.data();
-}
-
-const char *DW_VIRTUALITY_value_to_name(uint32_t val) {
- static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::VirtualityString(val);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_VIRTUALITY constant: 0x%x",
- val);
- return invalid;
- }
- return llvmstr.data();
-}
-
const char *DW_LANG_value_to_name(uint32_t val) {
static char invalid[100];
llvm::StringRef llvmstr = llvm::dwarf::LanguageString(val);
@@ -433,46 +389,6 @@ const char *DW_LANG_value_to_name(uint32_t val) {
return llvmstr.data();
}
-const char *DW_ID_value_to_name(uint32_t val) {
- static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::CaseString(val);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_ID constant: 0x%x", val);
- return invalid;
- }
- return llvmstr.data();
-}
-
-const char *DW_CC_value_to_name(uint32_t val) {
- static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::ConventionString(val);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_CC constant: 0x%x", val);
- return invalid;
- }
- return llvmstr.data();
-}
-
-const char *DW_INL_value_to_name(uint32_t val) {
- static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::InlineCodeString(val);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_INL constant: 0x%x", val);
- return invalid;
- }
- return llvmstr.data();
-}
-
-const char *DW_ORD_value_to_name(uint32_t val) {
- static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::ArrayOrderString(val);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_ORD constant: 0x%x", val);
- return invalid;
- }
- return llvmstr.data();
-}
-
const char *DW_LNS_value_to_name(uint32_t val) {
static char invalid[100];
llvm::StringRef llvmstr = llvm::dwarf::LNStandardString(val);
@@ -483,157 +399,4 @@ const char *DW_LNS_value_to_name(uint32_t val) {
return llvmstr.data();
}
-const char *DW_LNE_value_to_name(uint32_t val) {
- static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::LNExtendedString(val);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_LNE constant: 0x%x", val);
- return invalid;
- }
- return llvmstr.data();
-}
-
-const char *DW_MACINFO_value_to_name(uint32_t val) {
- static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::MacinfoString(val);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_MACINFO constant: 0x%x",
- val);
- return invalid;
- }
- return llvmstr.data();
-}
-
-const char *DW_CFA_value_to_name(uint32_t val, llvm::Triple::ArchType Arch) {
- static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::CallFrameString(val, Arch);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_CFA constant: 0x%x", val);
- return invalid;
- }
- return llvmstr.data();
-}
-
-DW_TAG_CategoryEnum get_tag_category(uint16_t tag) {
- switch (tag) {
- case DW_TAG_array_type:
- return TagCategoryType;
- case DW_TAG_class_type:
- return TagCategoryType;
- case DW_TAG_entry_point:
- return TagCategoryProgram;
- case DW_TAG_enumeration_type:
- return TagCategoryType;
- case DW_TAG_formal_parameter:
- return TagCategoryVariable;
- case DW_TAG_imported_declaration:
- return TagCategoryProgram;
- case DW_TAG_label:
- return TagCategoryProgram;
- case DW_TAG_lexical_block:
- return TagCategoryProgram;
- case DW_TAG_member:
- return TagCategoryType;
- case DW_TAG_pointer_type:
- return TagCategoryType;
- case DW_TAG_reference_type:
- return TagCategoryType;
- case DW_TAG_compile_unit:
- return TagCategoryProgram;
- case DW_TAG_string_type:
- return TagCategoryType;
- case DW_TAG_structure_type:
- return TagCategoryType;
- case DW_TAG_subroutine_type:
- return TagCategoryType;
- case DW_TAG_typedef:
- return TagCategoryType;
- case DW_TAG_union_type:
- return TagCategoryType;
- case DW_TAG_unspecified_parameters:
- return TagCategoryVariable;
- case DW_TAG_variant:
- return TagCategoryType;
- case DW_TAG_common_block:
- return TagCategoryProgram;
- case DW_TAG_common_inclusion:
- return TagCategoryProgram;
- case DW_TAG_inheritance:
- return TagCategoryType;
- case DW_TAG_inlined_subroutine:
- return TagCategoryProgram;
- case DW_TAG_module:
- return TagCategoryProgram;
- case DW_TAG_ptr_to_member_type:
- return TagCategoryType;
- case DW_TAG_set_type:
- return TagCategoryType;
- case DW_TAG_subrange_type:
- return TagCategoryType;
- case DW_TAG_with_stmt:
- return TagCategoryProgram;
- case DW_TAG_access_declaration:
- return TagCategoryProgram;
- case DW_TAG_base_type:
- return TagCategoryType;
- case DW_TAG_catch_block:
- return TagCategoryProgram;
- case DW_TAG_const_type:
- return TagCategoryType;
- case DW_TAG_constant:
- return TagCategoryVariable;
- case DW_TAG_enumerator:
- return TagCategoryType;
- case DW_TAG_file_type:
- return TagCategoryType;
- case DW_TAG_friend:
- return TagCategoryType;
- case DW_TAG_namelist:
- return TagCategoryVariable;
- case DW_TAG_namelist_item:
- return TagCategoryVariable;
- case DW_TAG_packed_type:
- return TagCategoryType;
- case DW_TAG_subprogram:
- return TagCategoryProgram;
- case DW_TAG_template_type_parameter:
- return TagCategoryType;
- case DW_TAG_template_value_parameter:
- return TagCategoryType;
- case DW_TAG_GNU_template_parameter_pack:
- return TagCategoryType;
- case DW_TAG_thrown_type:
- return TagCategoryType;
- case DW_TAG_try_block:
- return TagCategoryProgram;
- case DW_TAG_variant_part:
- return TagCategoryType;
- case DW_TAG_variable:
- return TagCategoryVariable;
- case DW_TAG_volatile_type:
- return TagCategoryType;
- case DW_TAG_dwarf_procedure:
- return TagCategoryProgram;
- case DW_TAG_restrict_type:
- return TagCategoryType;
- case DW_TAG_interface_type:
- return TagCategoryType;
- case DW_TAG_namespace:
- return TagCategoryProgram;
- case DW_TAG_imported_module:
- return TagCategoryProgram;
- case DW_TAG_unspecified_type:
- return TagCategoryType;
- case DW_TAG_partial_unit:
- return TagCategoryProgram;
- case DW_TAG_imported_unit:
- return TagCategoryProgram;
- case DW_TAG_shared_type:
- return TagCategoryType;
- default:
- break;
- }
- return TagCategoryProgram;
-}
-
} // namespace lldb_private
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
index 0f5a885efb86..d16cb07baf88 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
@@ -1,9 +1,8 @@
//===-- DWARFDefines.h ------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -15,23 +14,12 @@
namespace lldb_private {
-typedef uint32_t DRC_class; // Holds DRC_* class bitfields
-
-enum DW_TAG_Category {
- TagCategoryVariable,
- TagCategoryType,
- TagCategoryProgram,
- kNumTagCategories
-};
+enum class DWARFEnumState { MoreItems, Complete };
-typedef enum DW_TAG_Category DW_TAG_CategoryEnum;
+typedef uint32_t DRC_class; // Holds DRC_* class bitfields
const char *DW_TAG_value_to_name(uint32_t val);
-DW_TAG_CategoryEnum get_tag_category(uint16_t tag);
-
-const char *DW_CHILDREN_value_to_name(uint8_t val);
-
const char *DW_AT_value_to_name(uint32_t val);
const char *DW_FORM_value_to_name(uint32_t val);
@@ -42,32 +30,10 @@ DRC_class DW_OP_value_to_class(uint32_t val);
const char *DW_ATE_value_to_name(uint32_t val);
-const char *DW_ACCESS_value_to_name(uint32_t val);
-
-const char *DW_VIS_value_to_name(uint32_t val);
-
-const char *DW_VIRTUALITY_value_to_name(uint32_t val);
-
const char *DW_LANG_value_to_name(uint32_t val);
-const char *DW_ID_value_to_name(uint32_t val);
-
-const char *DW_CC_value_to_name(uint32_t val);
-
-const char *DW_INL_value_to_name(uint32_t val);
-
-const char *DW_ORD_value_to_name(uint32_t val);
-
const char *DW_LNS_value_to_name(uint32_t val);
-const char *DW_LNE_value_to_name(uint32_t val);
-
-const char *DW_MACINFO_value_to_name(uint32_t val);
-
-const char *DW_CFA_value_to_name(uint32_t val, llvm::Triple::ArchType Arch);
-
-const char *DW_GNU_EH_PE_value_to_name(uint32_t val);
-
/* These DRC are entirely our own construction,
although they are derived from various comments in the DWARF standard.
Most of these are not useful to the parser, but the DW_AT and DW_FORM
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index 5d2a8ffdb85b..046ae67446af 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -1,169 +1,30 @@
//===-- DWARFFormValue.cpp --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <assert.h>
+#include "lldb/Core/Module.h"
#include "lldb/Core/dwarf.h"
+#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/Stream.h"
-#include "DWARFUnit.h"
+#include "DWARFDebugInfo.h"
#include "DWARFFormValue.h"
+#include "DWARFUnit.h"
class DWARFUnit;
using namespace lldb_private;
-static uint8_t g_form_sizes_addr4[] = {
- 0, // 0x00 unused
- 4, // 0x01 DW_FORM_addr
- 0, // 0x02 unused
- 0, // 0x03 DW_FORM_block2
- 0, // 0x04 DW_FORM_block4
- 2, // 0x05 DW_FORM_data2
- 4, // 0x06 DW_FORM_data4
- 8, // 0x07 DW_FORM_data8
- 0, // 0x08 DW_FORM_string
- 0, // 0x09 DW_FORM_block
- 0, // 0x0a DW_FORM_block1
- 1, // 0x0b DW_FORM_data1
- 1, // 0x0c DW_FORM_flag
- 0, // 0x0d DW_FORM_sdata
- 4, // 0x0e DW_FORM_strp
- 0, // 0x0f DW_FORM_udata
- 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
- // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
- 1, // 0x11 DW_FORM_ref1
- 2, // 0x12 DW_FORM_ref2
- 4, // 0x13 DW_FORM_ref4
- 8, // 0x14 DW_FORM_ref8
- 0, // 0x15 DW_FORM_ref_udata
- 0, // 0x16 DW_FORM_indirect
- 4, // 0x17 DW_FORM_sec_offset
- 0, // 0x18 DW_FORM_exprloc
- 0, // 0x19 DW_FORM_flag_present
- 0, // 0x1a
- 0, // 0x1b
- 0, // 0x1c
- 0, // 0x1d
- 0, // 0x1e
- 0, // 0x1f
- 8, // 0x20 DW_FORM_ref_sig8
-
-};
-
-static uint8_t g_form_sizes_addr8[] = {
- 0, // 0x00 unused
- 8, // 0x01 DW_FORM_addr
- 0, // 0x02 unused
- 0, // 0x03 DW_FORM_block2
- 0, // 0x04 DW_FORM_block4
- 2, // 0x05 DW_FORM_data2
- 4, // 0x06 DW_FORM_data4
- 8, // 0x07 DW_FORM_data8
- 0, // 0x08 DW_FORM_string
- 0, // 0x09 DW_FORM_block
- 0, // 0x0a DW_FORM_block1
- 1, // 0x0b DW_FORM_data1
- 1, // 0x0c DW_FORM_flag
- 0, // 0x0d DW_FORM_sdata
- 4, // 0x0e DW_FORM_strp
- 0, // 0x0f DW_FORM_udata
- 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
- // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
- 1, // 0x11 DW_FORM_ref1
- 2, // 0x12 DW_FORM_ref2
- 4, // 0x13 DW_FORM_ref4
- 8, // 0x14 DW_FORM_ref8
- 0, // 0x15 DW_FORM_ref_udata
- 0, // 0x16 DW_FORM_indirect
- 4, // 0x17 DW_FORM_sec_offset
- 0, // 0x18 DW_FORM_exprloc
- 0, // 0x19 DW_FORM_flag_present
- 0, // 0x1a
- 0, // 0x1b
- 0, // 0x1c
- 0, // 0x1d
- 0, // 0x1e
- 0, // 0x1f
- 8, // 0x20 DW_FORM_ref_sig8
-};
-
-// Difference with g_form_sizes_addr8:
-// DW_FORM_strp and DW_FORM_sec_offset are 8 instead of 4
-static uint8_t g_form_sizes_addr8_dwarf64[] = {
- 0, // 0x00 unused
- 8, // 0x01 DW_FORM_addr
- 0, // 0x02 unused
- 0, // 0x03 DW_FORM_block2
- 0, // 0x04 DW_FORM_block4
- 2, // 0x05 DW_FORM_data2
- 4, // 0x06 DW_FORM_data4
- 8, // 0x07 DW_FORM_data8
- 0, // 0x08 DW_FORM_string
- 0, // 0x09 DW_FORM_block
- 0, // 0x0a DW_FORM_block1
- 1, // 0x0b DW_FORM_data1
- 1, // 0x0c DW_FORM_flag
- 0, // 0x0d DW_FORM_sdata
- 8, // 0x0e DW_FORM_strp
- 0, // 0x0f DW_FORM_udata
- 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
- // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
- 1, // 0x11 DW_FORM_ref1
- 2, // 0x12 DW_FORM_ref2
- 4, // 0x13 DW_FORM_ref4
- 8, // 0x14 DW_FORM_ref8
- 0, // 0x15 DW_FORM_ref_udata
- 0, // 0x16 DW_FORM_indirect
- 8, // 0x17 DW_FORM_sec_offset
- 0, // 0x18 DW_FORM_exprloc
- 0, // 0x19 DW_FORM_flag_present
- 0, // 0x1a
- 0, // 0x1b
- 0, // 0x1c
- 0, // 0x1d
- 0, // 0x1e
- 0, // 0x1f
- 8, // 0x20 DW_FORM_ref_sig8
-};
-
-DWARFFormValue::FixedFormSizes
-DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size,
- bool is_dwarf64) {
- if (!is_dwarf64) {
- switch (addr_size) {
- case 4:
- return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4));
- case 8:
- return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8));
- }
- } else {
- if (addr_size == 8)
- return FixedFormSizes(g_form_sizes_addr8_dwarf64,
- sizeof(g_form_sizes_addr8_dwarf64));
- // is_dwarf64 && addr_size == 4 : no provider does this.
- }
- return FixedFormSizes();
-}
-
-DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {}
-
-DWARFFormValue::DWARFFormValue(const DWARFUnit *cu)
- : m_cu(cu), m_form(0), m_value() {}
-
-DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form)
- : m_cu(cu), m_form(form), m_value() {}
-
void DWARFFormValue::Clear() {
- m_cu = nullptr;
+ m_unit = nullptr;
m_form = 0;
- memset(&m_value, 0, sizeof(m_value));
+ m_value = ValueTypeTag();
}
bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
@@ -173,7 +34,7 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
bool indirect = false;
bool is_block = false;
- m_value.data = NULL;
+ m_value.data = nullptr;
uint8_t ref_addr_size;
// Read the value for the form into value and follow and DW_FORM_indirect
// instances we run into
@@ -181,9 +42,9 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
indirect = false;
switch (m_form) {
case DW_FORM_addr:
- assert(m_cu);
+ assert(m_unit);
m_value.value.uval =
- data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_cu));
+ data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_unit));
break;
case DW_FORM_block1:
m_value.value.uval = data.GetU8(offset_ptr);
@@ -215,9 +76,7 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
case DW_FORM_strp:
case DW_FORM_line_strp:
case DW_FORM_sec_offset:
- assert(m_cu);
- m_value.value.uval =
- data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4);
+ m_value.value.uval = data.GetMaxU64(offset_ptr, 4);
break;
case DW_FORM_addrx1:
case DW_FORM_strx1:
@@ -257,11 +116,11 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
m_value.value.uval = data.GetULEB128(offset_ptr);
break;
case DW_FORM_ref_addr:
- assert(m_cu);
- if (m_cu->GetVersion() <= 2)
- ref_addr_size = m_cu->GetAddressByteSize();
+ assert(m_unit);
+ if (m_unit->GetVersion() <= 2)
+ ref_addr_size = m_unit->GetAddressByteSize();
else
- ref_addr_size = m_cu->IsDWARF64() ? 8 : 4;
+ ref_addr_size = 4;
m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size);
break;
case DW_FORM_indirect:
@@ -278,7 +137,7 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
if (is_block) {
m_value.data = data.PeekData(*offset_ptr, m_value.value.uval);
- if (m_value.data != NULL) {
+ if (m_value.data != nullptr) {
*offset_ptr += m_value.value.uval;
}
}
@@ -286,15 +145,68 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
return true;
}
+struct FormSize {
+ uint8_t valid:1, size:7;
+};
+static FormSize g_form_sizes[] = {
+ {0,0}, // 0x00 unused
+ {0,0}, // 0x01 DW_FORM_addr
+ {0,0}, // 0x02 unused
+ {0,0}, // 0x03 DW_FORM_block2
+ {0,0}, // 0x04 DW_FORM_block4
+ {1,2}, // 0x05 DW_FORM_data2
+ {1,4}, // 0x06 DW_FORM_data4
+ {1,8}, // 0x07 DW_FORM_data8
+ {0,0}, // 0x08 DW_FORM_string
+ {0,0}, // 0x09 DW_FORM_block
+ {0,0}, // 0x0a DW_FORM_block1
+ {1,1}, // 0x0b DW_FORM_data1
+ {1,1}, // 0x0c DW_FORM_flag
+ {0,0}, // 0x0d DW_FORM_sdata
+ {1,4}, // 0x0e DW_FORM_strp
+ {0,0}, // 0x0f DW_FORM_udata
+ {0,0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
+ // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
+ {1,1}, // 0x11 DW_FORM_ref1
+ {1,2}, // 0x12 DW_FORM_ref2
+ {1,4}, // 0x13 DW_FORM_ref4
+ {1,8}, // 0x14 DW_FORM_ref8
+ {0,0}, // 0x15 DW_FORM_ref_udata
+ {0,0}, // 0x16 DW_FORM_indirect
+ {1,4}, // 0x17 DW_FORM_sec_offset
+ {0,0}, // 0x18 DW_FORM_exprloc
+ {1,0}, // 0x19 DW_FORM_flag_present
+ {0,0}, // 0x1a
+ {0,0}, // 0x1b
+ {0,0}, // 0x1c
+ {0,0}, // 0x1d
+ {0,0}, // 0x1e
+ {0,0}, // 0x1f
+ {1,8}, // 0x20 DW_FORM_ref_sig8
+};
+
+llvm::Optional<uint8_t>
+DWARFFormValue::GetFixedSize(dw_form_t form, const DWARFUnit *u) {
+ if (form <= DW_FORM_ref_sig8 && g_form_sizes[form].valid)
+ return g_form_sizes[form].size;
+ if (form == DW_FORM_addr && u)
+ return u->GetAddressByteSize();
+ return llvm::None;
+}
+
+llvm::Optional<uint8_t> DWARFFormValue::GetFixedSize() const {
+ return GetFixedSize(m_form, m_unit);
+}
+
bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data,
lldb::offset_t *offset_ptr) const {
- return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu);
+ return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_unit);
}
bool DWARFFormValue::SkipValue(dw_form_t form,
const DWARFDataExtractor &debug_info_data,
lldb::offset_t *offset_ptr,
- const DWARFUnit *cu) {
+ const DWARFUnit *unit) {
uint8_t ref_addr_size;
switch (form) {
// Blocks if inlined data that have a length field and the data bytes inlined
@@ -328,17 +240,17 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
// Compile unit address sized values
case DW_FORM_addr:
- *offset_ptr += DWARFUnit::GetAddressByteSize(cu);
+ *offset_ptr += DWARFUnit::GetAddressByteSize(unit);
return true;
case DW_FORM_ref_addr:
ref_addr_size = 4;
- assert(cu); // CU must be valid for DW_FORM_ref_addr objects or we will get
- // this wrong
- if (cu->GetVersion() <= 2)
- ref_addr_size = cu->GetAddressByteSize();
+ assert(unit); // Unit must be valid for DW_FORM_ref_addr objects or we will
+ // get this wrong
+ if (unit->GetVersion() <= 2)
+ ref_addr_size = unit->GetAddressByteSize();
else
- ref_addr_size = cu->IsDWARF64() ? 8 : 4;
+ ref_addr_size = 4;
*offset_ptr += ref_addr_size;
return true;
@@ -373,8 +285,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
// 32 bit for DWARF 32, 64 for DWARF 64
case DW_FORM_sec_offset:
case DW_FORM_strp:
- assert(cu);
- *offset_ptr += (cu->IsDWARF64() ? 8 : 4);
+ *offset_ptr += 4;
return true;
// 4 byte values
@@ -407,7 +318,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
case DW_FORM_indirect: {
dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr,
- cu);
+ unit);
}
default:
@@ -418,7 +329,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
void DWARFFormValue::Dump(Stream &s) const {
uint64_t uvalue = Unsigned();
- bool cu_relative_offset = false;
+ bool unit_relative_offset = false;
switch (m_form) {
case DW_FORM_addr:
@@ -495,9 +406,9 @@ void DWARFFormValue::Dump(Stream &s) const {
} break;
case DW_FORM_ref_addr: {
- assert(m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will
- // get this wrong
- if (m_cu->GetVersion() <= 2)
+ assert(m_unit); // Unit must be valid for DW_FORM_ref_addr objects or we
+ // will get this wrong
+ if (m_unit->GetVersion() <= 2)
s.Address(uvalue, sizeof(uint64_t) * 2);
else
s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't
@@ -505,19 +416,19 @@ void DWARFFormValue::Dump(Stream &s) const {
break;
}
case DW_FORM_ref1:
- cu_relative_offset = true;
+ unit_relative_offset = true;
break;
case DW_FORM_ref2:
- cu_relative_offset = true;
+ unit_relative_offset = true;
break;
case DW_FORM_ref4:
- cu_relative_offset = true;
+ unit_relative_offset = true;
break;
case DW_FORM_ref8:
- cu_relative_offset = true;
+ unit_relative_offset = true;
break;
case DW_FORM_ref_udata:
- cu_relative_offset = true;
+ unit_relative_offset = true;
break;
// All DW_FORM_indirect attributes should be resolved prior to calling this
@@ -532,33 +443,29 @@ void DWARFFormValue::Dump(Stream &s) const {
break;
}
- if (cu_relative_offset) {
- assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
- // unit relative or we will get this wrong
- s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset());
+ if (unit_relative_offset) {
+ assert(m_unit); // Unit must be valid for DW_FORM_ref forms that are compile
+ // unit relative or we will get this wrong
+ s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_unit->GetOffset());
}
}
const char *DWARFFormValue::AsCString() const {
- SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
+ SymbolFileDWARF &symbol_file = m_unit->GetSymbolFileDWARF();
if (m_form == DW_FORM_string) {
return m_value.value.cstr;
} else if (m_form == DW_FORM_strp) {
- if (!symbol_file)
- return nullptr;
-
- return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval);
+ return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr(
+ m_value.value.uval);
} else if (m_form == DW_FORM_GNU_str_index) {
- if (!symbol_file)
- return nullptr;
-
- uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4;
+ uint32_t index_size = 4;
lldb::offset_t offset = m_value.value.uval * index_size;
dw_offset_t str_offset =
- symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset,
- index_size);
- return symbol_file->get_debug_str_data().PeekCStr(str_offset);
+ symbol_file.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64(
+ &offset, index_size);
+ return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr(
+ str_offset);
}
if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 ||
@@ -566,44 +473,41 @@ const char *DWARFFormValue::AsCString() const {
m_form == DW_FORM_strx4) {
// The same code as above.
- if (!symbol_file)
- return nullptr;
-
- uint32_t indexSize = m_cu->IsDWARF64() ? 8 : 4;
+ uint32_t indexSize = 4;
lldb::offset_t offset =
- m_cu->GetStrOffsetsBase() + m_value.value.uval * indexSize;
+ m_unit->GetStrOffsetsBase() + m_value.value.uval * indexSize;
dw_offset_t strOffset =
- symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize);
- return symbol_file->get_debug_str_data().PeekCStr(strOffset);
+ symbol_file.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64(
+ &offset, indexSize);
+ return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr(strOffset);
}
if (m_form == DW_FORM_line_strp)
- return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval);
+ return symbol_file.GetDWARFContext().getOrLoadLineStrData().PeekCStr(
+ m_value.value.uval);
return nullptr;
}
dw_addr_t DWARFFormValue::Address() const {
- SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
+ SymbolFileDWARF &symbol_file = m_unit->GetSymbolFileDWARF();
if (m_form == DW_FORM_addr)
return Unsigned();
- assert(m_cu);
+ assert(m_unit);
assert(m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx ||
m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 ||
m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4);
- if (!symbol_file)
- return 0;
-
- uint32_t index_size = m_cu->GetAddressByteSize();
- dw_offset_t addr_base = m_cu->GetAddrBase();
+ uint32_t index_size = m_unit->GetAddressByteSize();
+ dw_offset_t addr_base = m_unit->GetAddrBase();
lldb::offset_t offset = addr_base + m_value.value.uval * index_size;
- return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size);
+ return symbol_file.GetDWARFContext().getOrLoadAddrData().GetMaxU64(
+ &offset, index_size);
}
-uint64_t DWARFFormValue::Reference() const {
+DWARFDIE DWARFFormValue::Reference() const {
uint64_t value = m_value.value.uval;
switch (m_form) {
case DW_FORM_ref1:
@@ -611,17 +515,40 @@ uint64_t DWARFFormValue::Reference() const {
case DW_FORM_ref4:
case DW_FORM_ref8:
case DW_FORM_ref_udata:
- assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
- // unit relative or we will get this wrong
- return value + m_cu->GetOffset();
+ assert(m_unit); // Unit must be valid for DW_FORM_ref forms that are compile
+ // unit relative or we will get this wrong
+ value += m_unit->GetOffset();
+ if (!m_unit->ContainsDIEOffset(value)) {
+ m_unit->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+ "DW_FORM_ref* DIE reference 0x%" PRIx64 " is outside of its CU",
+ value);
+ return {};
+ }
+ return const_cast<DWARFUnit *>(m_unit)->GetDIE(value);
- case DW_FORM_ref_addr:
- case DW_FORM_ref_sig8:
- case DW_FORM_GNU_ref_alt:
- return value;
+ case DW_FORM_ref_addr: {
+ DWARFUnit *ref_cu =
+ m_unit->GetSymbolFileDWARF().DebugInfo()->GetUnitContainingDIEOffset(
+ DIERef::Section::DebugInfo, value);
+ if (!ref_cu) {
+ m_unit->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+ "DW_FORM_ref_addr DIE reference 0x%" PRIx64 " has no matching CU",
+ value);
+ return {};
+ }
+ return ref_cu->GetDIE(value);
+ }
+
+ case DW_FORM_ref_sig8: {
+ DWARFTypeUnit *tu =
+ m_unit->GetSymbolFileDWARF().DebugInfo()->GetTypeUnitForHash(value);
+ if (!tu)
+ return {};
+ return tu->GetDIE(tu->GetTypeOffset());
+ }
default:
- return DW_INVALID_OFFSET;
+ return {};
}
}
@@ -682,6 +609,7 @@ int DWARFFormValue::Compare(const DWARFFormValue &a_value,
return 1;
switch (a_form) {
case DW_FORM_addr:
+ case DW_FORM_addrx:
case DW_FORM_flag:
case DW_FORM_data1:
case DW_FORM_data2:
@@ -721,7 +649,7 @@ int DWARFFormValue::Compare(const DWARFFormValue &a_value,
return 0;
else if (a_string && b_string)
return strcmp(a_string, b_string);
- else if (a_string == NULL)
+ else if (a_string == nullptr)
return -1; // A string is NULL, and B is valid
else
return 1; // A string valid, and B is NULL
@@ -747,8 +675,8 @@ int DWARFFormValue::Compare(const DWARFFormValue &a_value,
case DW_FORM_ref4:
case DW_FORM_ref8:
case DW_FORM_ref_udata: {
- uint64_t a = a_value.Reference();
- uint64_t b = b_value.Reference();
+ uint64_t a = a_value.m_value.value.uval;
+ uint64_t b = b_value.m_value.value.uval;
if (a < b)
return -1;
if (a > b)
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index 0890f0c1bfc5..848db2990ded 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -1,9 +1,8 @@
//===-- DWARFFormValue.h ----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -12,14 +11,16 @@
#include "DWARFDataExtractor.h"
#include <stddef.h>
+#include "llvm/ADT/Optional.h"
class DWARFUnit;
class SymbolFileDWARF;
+class DWARFDIE;
class DWARFFormValue {
public:
typedef struct ValueTypeTag {
- ValueTypeTag() : value(), data(NULL) { value.uval = 0; }
+ ValueTypeTag() : value(), data(nullptr) { value.uval = 0; }
union {
uint64_t uval;
@@ -29,24 +30,6 @@ public:
const uint8_t *data;
} ValueType;
- class FixedFormSizes {
- public:
- FixedFormSizes() : m_fix_sizes(nullptr), m_size(0) {}
-
- FixedFormSizes(const uint8_t *fix_sizes, size_t size)
- : m_fix_sizes(fix_sizes), m_size(size) {}
-
- uint8_t GetSize(uint32_t index) const {
- return index < m_size ? m_fix_sizes[index] : 0;
- }
-
- bool Empty() const { return m_size == 0; }
-
- private:
- const uint8_t *m_fix_sizes;
- size_t m_size;
- };
-
enum {
eValueTypeInvalid = 0,
eValueTypeUnsigned,
@@ -55,11 +38,11 @@ public:
eValueTypeBlock
};
- DWARFFormValue();
- DWARFFormValue(const DWARFUnit *cu);
- DWARFFormValue(const DWARFUnit *cu, dw_form_t form);
- const DWARFUnit *GetCompileUnit() const { return m_cu; }
- void SetCompileUnit(const DWARFUnit *cu) { m_cu = cu; }
+ DWARFFormValue() = default;
+ DWARFFormValue(const DWARFUnit *unit) : m_unit(unit) {}
+ DWARFFormValue(const DWARFUnit *unit, dw_form_t form)
+ : m_unit(unit), m_form(form) {}
+ void SetUnit(const DWARFUnit *unit) { m_unit = unit; }
dw_form_t Form() const { return m_form; }
dw_form_t& FormRef() { return m_form; }
void SetForm(dw_form_t form) { m_form = form; }
@@ -71,7 +54,10 @@ public:
bool ExtractValue(const lldb_private::DWARFDataExtractor &data,
lldb::offset_t *offset_ptr);
const uint8_t *BlockData() const;
- uint64_t Reference() const;
+ static llvm::Optional<uint8_t> GetFixedSize(dw_form_t form,
+ const DWARFUnit *u);
+ llvm::Optional<uint8_t> GetFixedSize() const;
+ DWARFDIE Reference() const;
uint64_t Reference(dw_offset_t offset) const;
bool Boolean() const { return m_value.value.uval != 0; }
uint64_t Unsigned() const { return m_value.value.uval; }
@@ -85,18 +71,18 @@ public:
lldb::offset_t *offset_ptr) const;
static bool SkipValue(const dw_form_t form,
const lldb_private::DWARFDataExtractor &debug_info_data,
- lldb::offset_t *offset_ptr, const DWARFUnit *cu);
+ lldb::offset_t *offset_ptr, const DWARFUnit *unit);
static bool IsBlockForm(const dw_form_t form);
static bool IsDataForm(const dw_form_t form);
- static FixedFormSizes GetFixedFormSizesForAddressSize(uint8_t addr_size,
- bool is_dwarf64);
static int Compare(const DWARFFormValue &a, const DWARFFormValue &b);
void Clear();
static bool FormIsSupported(dw_form_t form);
protected:
- const DWARFUnit *m_cu; // Compile unit for this form
- dw_form_t m_form; // Form for this value
+ // Compile unit where m_value was located.
+ // It may be different from compile unit where m_value refers to.
+ const DWARFUnit *m_unit = nullptr; // Unit for this form
+ dw_form_t m_form = 0; // Form for this value
ValueType m_value; // Contains all data for the form
};
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
index 4577f0557a1d..c122f756e81a 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
@@ -1,17 +1,15 @@
//===-- DWARFIndex.cpp -----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
-#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
-#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
-
#include "Plugins/Language/ObjC/ObjCLanguage.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
+#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
using namespace lldb_private;
using namespace lldb;
@@ -19,13 +17,13 @@ using namespace lldb;
DWARFIndex::~DWARFIndex() = default;
void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
- DWARFDebugInfo &info,
+ SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
uint32_t name_type_mask,
std::vector<DWARFDIE> &dies) {
- DWARFDIE die = info.GetDIE(ref);
+ DWARFDIE die = dwarf.GetDIE(ref);
if (!die) {
- ReportInvalidDIEOffset(ref.die_offset, name);
+ ReportInvalidDIERef(ref, name);
return;
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
index 77af67b8e60f..e3c7c5e63ac8 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
@@ -1,9 +1,8 @@
//===-- DWARFIndex.h -------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -14,7 +13,6 @@
#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
#include "Plugins/SymbolFile/DWARF/DWARFFormValue.h"
-class DWARFDebugInfo;
class DWARFDeclContext;
class DWARFDIE;
@@ -41,15 +39,14 @@ public:
virtual void GetTypes(ConstString name, DIEArray &offsets) = 0;
virtual void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) = 0;
virtual void GetNamespaces(ConstString name, DIEArray &offsets) = 0;
- virtual void GetFunctions(ConstString name, DWARFDebugInfo &info,
+ virtual void GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
uint32_t name_type_mask,
std::vector<DWARFDIE> &dies) = 0;
virtual void GetFunctions(const RegularExpression &regex,
DIEArray &offsets) = 0;
- virtual void ReportInvalidDIEOffset(dw_offset_t offset,
- llvm::StringRef name) = 0;
+ virtual void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) = 0;
virtual void Dump(Stream &s) = 0;
protected:
@@ -60,7 +57,7 @@ protected:
/// "parent_decl_ctx" and "name_type_mask", it is inserted into the "dies"
/// vector.
void ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
- DWARFDebugInfo &info,
+ SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
uint32_t name_type_mask, std::vector<DWARFDIE> &dies);
};
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
new file mode 100644
index 000000000000..fcc031bf1ea0
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
@@ -0,0 +1,23 @@
+//===-- DWARFTypeUnit.cpp ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFTypeUnit.h"
+
+#include "SymbolFileDWARF.h"
+#include "lldb/Utility/Stream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void DWARFTypeUnit::Dump(Stream *s) const {
+ s->Printf("0x%8.8x: Type Unit: length = 0x%8.8x, version = 0x%4.4x, "
+ "abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at "
+ "{0x%8.8x})\n",
+ GetOffset(), GetLength(), GetVersion(), GetAbbrevOffset(),
+ GetAddressByteSize(), GetNextUnitOffset());
+}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
new file mode 100644
index 000000000000..6ff73ecd8efa
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
@@ -0,0 +1,37 @@
+//===-- DWARFTypeUnit.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SymbolFileDWARF_DWARFTypeUnit_h_
+#define SymbolFileDWARF_DWARFTypeUnit_h_
+
+#include "DWARFUnit.h"
+#include "llvm/Support/Error.h"
+
+class DWARFTypeUnit : public DWARFUnit {
+public:
+ void BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) override {}
+
+ void Dump(lldb_private::Stream *s) const override;
+
+ uint64_t GetTypeHash() { return m_header.GetTypeHash(); }
+
+ dw_offset_t GetTypeOffset() { return GetOffset() + m_header.GetTypeOffset(); }
+
+ static bool classof(const DWARFUnit *unit) { return unit->IsTypeUnit(); }
+
+private:
+ DWARFTypeUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
+ const DWARFUnitHeader &header,
+ const DWARFAbbreviationDeclarationSet &abbrevs,
+ DIERef::Section section)
+ : DWARFUnit(dwarf, uid, header, abbrevs, section) {}
+
+ friend class DWARFUnit;
+};
+
+#endif // SymbolFileDWARF_DWARFTypeUnit_h_
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 7afc71bc24f0..33e83d1fe57f 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -1,9 +1,8 @@
//===-- DWARFUnit.cpp -------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,18 +10,17 @@
#include "lldb/Core/Module.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Symbol/CompileUnit.h"
-#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/Object/Error.h"
-#include "DWARFDIECollection.h"
+#include "DWARFCompileUnit.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
+#include "DWARFTypeUnit.h"
#include "LogChannelDWARF.h"
-#include "SymbolFileDWARFDebugMap.h"
#include "SymbolFileDWARFDwo.h"
using namespace lldb;
@@ -31,14 +29,16 @@ using namespace std;
extern int g_verbose;
-DWARFUnit::DWARFUnit(SymbolFileDWARF *dwarf)
- : m_dwarf(dwarf), m_cancel_scopes(false) {}
+DWARFUnit::DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
+ const DWARFUnitHeader &header,
+ const DWARFAbbreviationDeclarationSet &abbrevs,
+ DIERef::Section section)
+ : UserID(uid), m_dwarf(dwarf), m_header(header), m_abbrevs(&abbrevs),
+ m_cancel_scopes(false), m_section(section) {}
-DWARFUnit::~DWARFUnit() {}
+DWARFUnit::~DWARFUnit() = default;
-//----------------------------------------------------------------------
// Parses first DIE of a compile unit.
-//----------------------------------------------------------------------
void DWARFUnit::ExtractUnitDIEIfNeeded() {
{
llvm::sys::ScopedReader lock(m_first_die_mutex);
@@ -50,8 +50,8 @@ void DWARFUnit::ExtractUnitDIEIfNeeded() {
return; // Already parsed
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat, "%8.8x: DWARFUnit::ExtractUnitDIEIfNeeded()", m_offset);
+ Timer scoped_timer(func_cat, "%8.8x: DWARFUnit::ExtractUnitDIEIfNeeded()",
+ GetOffset());
// Set the offset to that of the first DIE and calculate the start of the
// next compilation unit header.
@@ -60,22 +60,15 @@ void DWARFUnit::ExtractUnitDIEIfNeeded() {
// We are in our compile unit, parse starting at the offset we were told to
// parse
const DWARFDataExtractor &data = GetData();
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
- IsDWARF64());
- if (offset < GetNextCompileUnitOffset() &&
- m_first_die.FastExtract(data, this, fixed_form_sizes, &offset)) {
+ if (offset < GetNextUnitOffset() &&
+ m_first_die.Extract(data, this, &offset)) {
AddUnitDIE(m_first_die);
return;
}
-
- ExtractDIEsEndCheck(offset);
}
-//----------------------------------------------------------------------
// Parses a compile unit and indexes its DIEs if it hasn't already been done.
// It will leave this compile unit extracted forever.
-//----------------------------------------------------------------------
void DWARFUnit::ExtractDIEsIfNeeded() {
m_cancel_scopes = true;
@@ -91,15 +84,13 @@ void DWARFUnit::ExtractDIEsIfNeeded() {
ExtractDIEsRWLocked();
}
-//----------------------------------------------------------------------
// Parses a compile unit and indexes its DIEs if it hasn't already been done.
// It will clear this compile unit after returned instance gets out of scope,
// no other ScopedExtractDIEs instance is running for this compile unit
// and no ExtractDIEsIfNeeded() has been executed during this ScopedExtractDIEs
// lifetime.
-//----------------------------------------------------------------------
DWARFUnit::ScopedExtractDIEs DWARFUnit::ExtractDIEsScoped() {
- ScopedExtractDIEs scoped(this);
+ ScopedExtractDIEs scoped(*this);
{
llvm::sys::ScopedReader lock(m_die_array_mutex);
@@ -118,8 +109,7 @@ DWARFUnit::ScopedExtractDIEs DWARFUnit::ExtractDIEsScoped() {
return scoped;
}
-DWARFUnit::ScopedExtractDIEs::ScopedExtractDIEs(DWARFUnit *cu) : m_cu(cu) {
- lldbassert(m_cu);
+DWARFUnit::ScopedExtractDIEs::ScopedExtractDIEs(DWARFUnit &cu) : m_cu(&cu) {
m_cu->m_die_array_scoped_mutex.lock_shared();
}
@@ -150,33 +140,21 @@ DWARFUnit::ScopedExtractDIEs &DWARFUnit::ScopedExtractDIEs::operator=(
return *this;
}
-//----------------------------------------------------------------------
// Parses a compile unit and indexes its DIEs, m_die_array_mutex must be
// held R/W and m_die_array must be empty.
-//----------------------------------------------------------------------
void DWARFUnit::ExtractDIEsRWLocked() {
llvm::sys::ScopedWriter first_die_lock(m_first_die_mutex);
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat, "%8.8x: DWARFUnit::ExtractDIEsIfNeeded()", m_offset);
+ Timer scoped_timer(func_cat, "%8.8x: DWARFUnit::ExtractDIEsIfNeeded()",
+ GetOffset());
// Set the offset to that of the first DIE and calculate the start of the
// next compilation unit header.
lldb::offset_t offset = GetFirstDIEOffset();
- lldb::offset_t next_cu_offset = GetNextCompileUnitOffset();
+ lldb::offset_t next_cu_offset = GetNextUnitOffset();
DWARFDebugInfoEntry die;
- // Keep a flat array of the DIE for binary lookup by DIE offset
- Log *log(
- LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS));
- if (log) {
- m_dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
- log,
- "DWARFUnit::ExtractDIEsIfNeeded () for compile unit at "
- ".debug_info[0x%8.8x]",
- GetOffset());
- }
uint32_t depth = 0;
// We are in our compile unit, parse starting at the offset we were told to
@@ -186,11 +164,7 @@ void DWARFUnit::ExtractDIEsRWLocked() {
die_index_stack.reserve(32);
die_index_stack.push_back(0);
bool prev_die_had_children = false;
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
- IsDWARF64());
- while (offset < next_cu_offset &&
- die.FastExtract(data, this, fixed_form_sizes, &offset)) {
+ while (offset < next_cu_offset && die.Extract(data, this, &offset)) {
const bool null_die = die.IsNULL();
if (depth == 0) {
assert(m_die_array.empty() && "Compile unit DIE already added");
@@ -208,6 +182,17 @@ void DWARFUnit::ExtractDIEsRWLocked() {
if (!m_first_die)
AddUnitDIE(m_die_array.front());
+
+ // With -fsplit-dwarf-inlining, clang will emit non-empty skeleton compile
+ // units. We are not able to access these DIE *and* the dwo file
+ // simultaneously. We also don't need to do that as the dwo file will
+ // contain a superset of information. So, we don't even attempt to parse
+ // any remaining DIEs.
+ if (m_dwo_symbol_file) {
+ m_die_array.front().SetHasChildren(false);
+ break;
+ }
+
} else {
if (null_die) {
if (prev_die_had_children) {
@@ -264,40 +249,12 @@ void DWARFUnit::ExtractDIEsRWLocked() {
m_die_array.shrink_to_fit();
- ExtractDIEsEndCheck(offset);
-
if (m_dwo_symbol_file) {
DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit();
dwo_cu->ExtractDIEsIfNeeded();
}
}
-//--------------------------------------------------------------------------
-// Final checks for both ExtractUnitDIEIfNeeded() and ExtractDIEsIfNeeded().
-//--------------------------------------------------------------------------
-void DWARFUnit::ExtractDIEsEndCheck(lldb::offset_t offset) const {
- // Give a little bit of info if we encounter corrupt DWARF (our offset should
- // always terminate at or before the start of the next compilation unit
- // header).
- if (offset > GetNextCompileUnitOffset()) {
- m_dwarf->GetObjectFile()->GetModule()->ReportWarning(
- "DWARF compile unit extends beyond its bounds cu 0x%8.8x at "
- "0x%8.8" PRIx64 "\n",
- GetOffset(), offset);
- }
-
- Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
- if (log && log->GetVerbose()) {
- StreamString strm;
- Dump(&strm);
- if (m_die_array.empty())
- strm.Printf("error: no DIE for compile unit");
- else
- m_die_array[0].Dump(m_dwarf, this, strm, UINT32_MAX);
- log->PutString(strm.GetString());
- }
-}
-
// This is used when a split dwarf is enabled.
// A skeleton compilation unit may contain the DW_AT_str_offsets_base attribute
// that points to the first string offset of the CU contribution to the
@@ -308,7 +265,7 @@ static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu) {
lldb::offset_t baseOffset = 0;
const DWARFDataExtractor &strOffsets =
- dwo_cu->GetSymbolFileDWARF()->get_debug_str_offsets_data();
+ dwo_cu->GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData();
uint64_t length = strOffsets.GetU32(&baseOffset);
if (length == 0xffffffff)
length = strOffsets.GetU64(&baseOffset);
@@ -325,28 +282,50 @@ static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu) {
// m_die_array_mutex must be already held as read/write.
void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
- dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned(
- m_dwarf, this, DW_AT_addr_base, LLDB_INVALID_ADDRESS);
- if (addr_base != LLDB_INVALID_ADDRESS)
- SetAddrBase(addr_base);
-
- dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned(
- m_dwarf, this, DW_AT_rnglists_base, LLDB_INVALID_ADDRESS);
- if (ranges_base != LLDB_INVALID_ADDRESS)
- SetRangesBase(ranges_base);
-
- SetStrOffsetsBase(cu_die.GetAttributeValueAsUnsigned(
- m_dwarf, this, DW_AT_str_offsets_base, 0));
-
- uint64_t base_addr = cu_die.GetAttributeValueAsAddress(
- m_dwarf, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
- if (base_addr == LLDB_INVALID_ADDRESS)
- base_addr = cu_die.GetAttributeValueAsAddress(
- m_dwarf, this, DW_AT_entry_pc, 0);
- SetBaseAddress(base_addr);
+ llvm::Optional<uint64_t> addr_base, gnu_addr_base, ranges_base,
+ gnu_ranges_base;
+
+ DWARFAttributes attributes;
+ size_t num_attributes = cu_die.GetAttributes(this, attributes);
+ for (size_t i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ if (!attributes.ExtractFormValueAtIndex(i, form_value))
+ continue;
+ switch (attr) {
+ case DW_AT_addr_base:
+ addr_base = form_value.Unsigned();
+ SetAddrBase(*addr_base);
+ break;
+ case DW_AT_rnglists_base:
+ ranges_base = form_value.Unsigned();
+ SetRangesBase(*ranges_base);
+ break;
+ case DW_AT_str_offsets_base:
+ SetStrOffsetsBase(form_value.Unsigned());
+ break;
+ case DW_AT_low_pc:
+ SetBaseAddress(form_value.Address());
+ break;
+ case DW_AT_entry_pc:
+ // If the value was already set by DW_AT_low_pc, don't update it.
+ if (m_base_addr == LLDB_INVALID_ADDRESS)
+ SetBaseAddress(form_value.Address());
+ break;
+ case DW_AT_stmt_list:
+ m_line_table_offset = form_value.Unsigned();
+ break;
+ case DW_AT_GNU_addr_base:
+ gnu_addr_base = form_value.Unsigned();
+ break;
+ case DW_AT_GNU_ranges_base:
+ gnu_ranges_base = form_value.Unsigned();
+ break;
+ }
+ }
std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file =
- m_dwarf->GetDwoSymbolFileForCompileUnit(*this, cu_die);
+ m_dwarf.GetDwoSymbolFileForCompileUnit(*this, cu_die);
if (!dwo_symbol_file)
return;
@@ -359,7 +338,7 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
return; // Can't fetch the compile unit DIE from the dwo file.
uint64_t main_dwo_id =
- cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_GNU_dwo_id, 0);
+ cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, 0);
uint64_t sub_dwo_id =
dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0);
if (main_dwo_id != sub_dwo_id)
@@ -374,19 +353,20 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
// attributes which were applicable to the DWO units. The corresponding
// DW_AT_* attributes standardized in DWARF v5 are also applicable to the main
// unit in contrast.
- if (addr_base == LLDB_INVALID_ADDRESS)
- addr_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf, this,
- DW_AT_GNU_addr_base, 0);
- dwo_cu->SetAddrBase(addr_base);
-
- if (ranges_base == LLDB_INVALID_ADDRESS)
- ranges_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf, this,
- DW_AT_GNU_ranges_base, 0);
- dwo_cu->SetRangesBase(ranges_base);
-
- dwo_cu->SetBaseObjOffset(m_offset);
-
- SetDwoStrOffsetsBase(dwo_cu);
+ if (addr_base)
+ dwo_cu->SetAddrBase(*addr_base);
+ else if (gnu_addr_base)
+ dwo_cu->SetAddrBase(*gnu_addr_base);
+
+ if (ranges_base)
+ dwo_cu->SetRangesBase(*ranges_base);
+ else if (gnu_ranges_base)
+ dwo_cu->SetRangesBase(*gnu_ranges_base);
+
+ for (size_t i = 0; i < m_dwo_symbol_file->DebugInfo()->GetNumUnits(); ++i) {
+ DWARFUnit *unit = m_dwo_symbol_file->DebugInfo()->GetUnitAtIndex(i);
+ SetDwoStrOffsetsBase(unit);
+ }
}
DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) {
@@ -401,35 +381,21 @@ DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) {
}
size_t DWARFUnit::AppendDIEsWithTag(const dw_tag_t tag,
- DWARFDIECollection &dies,
- uint32_t depth) const {
- size_t old_size = dies.Size();
+ std::vector<DWARFDIE> &dies,
+ uint32_t depth) const {
+ size_t old_size = dies.size();
{
llvm::sys::ScopedReader lock(m_die_array_mutex);
DWARFDebugInfoEntry::const_iterator pos;
DWARFDebugInfoEntry::const_iterator end = m_die_array.end();
for (pos = m_die_array.begin(); pos != end; ++pos) {
if (pos->Tag() == tag)
- dies.Append(DWARFDIE(this, &(*pos)));
+ dies.emplace_back(this, &(*pos));
}
}
// Return the number of DIEs added to the collection
- return dies.Size() - old_size;
-}
-
-
-lldb::user_id_t DWARFUnit::GetID() const {
- dw_offset_t local_id =
- m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset;
- if (m_dwarf)
- return DIERef(local_id, local_id).GetUID(m_dwarf);
- else
- return local_id;
-}
-
-dw_offset_t DWARFUnit::GetNextCompileUnitOffset() const {
- return m_offset + GetLengthByteSize() + GetLength();
+ return dies.size() - old_size;
}
size_t DWARFUnit::GetDebugInfoSize() const {
@@ -444,16 +410,17 @@ dw_offset_t DWARFUnit::GetAbbrevOffset() const {
return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET;
}
+dw_offset_t DWARFUnit::GetLineTableOffset() {
+ ExtractUnitDIEIfNeeded();
+ return m_line_table_offset;
+}
+
void DWARFUnit::SetAddrBase(dw_addr_t addr_base) { m_addr_base = addr_base; }
void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) {
m_ranges_base = ranges_base;
}
-void DWARFUnit::SetBaseObjOffset(dw_offset_t base_obj_offset) {
- m_base_obj_offset = base_obj_offset;
-}
-
void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) {
m_str_offsets_base = str_offsets_base;
}
@@ -467,132 +434,27 @@ void DWARFUnit::ClearDIEsRWLocked() {
m_dwo_symbol_file->GetCompileUnit()->ClearDIEsRWLocked();
}
-void DWARFUnit::BuildAddressRangeTable(SymbolFileDWARF *dwarf,
- DWARFDebugAranges *debug_aranges) {
- // This function is usually called if there in no .debug_aranges section in
- // order to produce a compile unit level set of address ranges that is
- // accurate.
-
- size_t num_debug_aranges = debug_aranges->GetNumRanges();
-
- // First get the compile unit DIE only and check if it has a DW_AT_ranges
- const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
-
- const dw_offset_t cu_offset = GetOffset();
- if (die) {
- DWARFRangeList ranges;
- const size_t num_ranges =
- die->GetAttributeAddressRanges(dwarf, this, ranges, false);
- if (num_ranges > 0) {
- // This compile unit has DW_AT_ranges, assume this is correct if it is
- // present since clang no longer makes .debug_aranges by default and it
- // emits DW_AT_ranges for DW_TAG_compile_units. GCC also does this with
- // recent GCC builds.
- for (size_t i = 0; i < num_ranges; ++i) {
- const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
- debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
- range.GetRangeEnd());
- }
-
- return; // We got all of our ranges from the DW_AT_ranges attribute
- }
- }
- // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF
-
- // If the DIEs weren't parsed, then we don't want all dies for all compile
- // units to stay loaded when they weren't needed. So we can end up parsing
- // the DWARF and then throwing them all away to keep memory usage down.
- ScopedExtractDIEs clear_dies(ExtractDIEsScoped());
-
- die = DIEPtr();
- if (die)
- die->BuildAddressRangeTable(dwarf, this, debug_aranges);
-
- if (debug_aranges->GetNumRanges() == num_debug_aranges) {
- // We got nothing from the functions, maybe we have a line tables only
- // situation. Check the line tables and build the arange table from this.
- SymbolContext sc;
- sc.comp_unit = dwarf->GetCompUnitForDWARFCompUnit(this);
- if (sc.comp_unit) {
- SymbolFileDWARFDebugMap *debug_map_sym_file =
- m_dwarf->GetDebugMapSymfile();
- if (debug_map_sym_file == NULL) {
- LineTable *line_table = sc.comp_unit->GetLineTable();
-
- if (line_table) {
- LineTable::FileAddressRanges file_ranges;
- const bool append = true;
- const size_t num_ranges =
- line_table->GetContiguousFileAddressRanges(file_ranges, append);
- for (uint32_t idx = 0; idx < num_ranges; ++idx) {
- const LineTable::FileAddressRanges::Entry &range =
- file_ranges.GetEntryRef(idx);
- debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
- range.GetRangeEnd());
- }
- }
- } else
- debug_map_sym_file->AddOSOARanges(dwarf, debug_aranges);
- }
- }
-
- if (debug_aranges->GetNumRanges() == num_debug_aranges) {
- // We got nothing from the functions, maybe we have a line tables only
- // situation. Check the line tables and build the arange table from this.
- SymbolContext sc;
- sc.comp_unit = dwarf->GetCompUnitForDWARFCompUnit(this);
- if (sc.comp_unit) {
- LineTable *line_table = sc.comp_unit->GetLineTable();
-
- if (line_table) {
- LineTable::FileAddressRanges file_ranges;
- const bool append = true;
- const size_t num_ranges =
- line_table->GetContiguousFileAddressRanges(file_ranges, append);
- for (uint32_t idx = 0; idx < num_ranges; ++idx) {
- const LineTable::FileAddressRanges::Entry &range =
- file_ranges.GetEntryRef(idx);
- debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(),
- range.GetRangeEnd());
- }
- }
- }
- }
-}
-
lldb::ByteOrder DWARFUnit::GetByteOrder() const {
- return m_dwarf->GetObjectFile()->GetByteOrder();
+ return m_dwarf.GetObjectFile()->GetByteOrder();
}
TypeSystem *DWARFUnit::GetTypeSystem() {
- if (m_dwarf)
- return m_dwarf->GetTypeSystemForLanguage(GetLanguageType());
- else
- return nullptr;
-}
-
-DWARFFormValue::FixedFormSizes DWARFUnit::GetFixedFormSizes() {
- return DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
- IsDWARF64());
+ return m_dwarf.GetTypeSystemForLanguage(GetLanguageType());
}
void DWARFUnit::SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; }
-//----------------------------------------------------------------------
// Compare function DWARFDebugAranges::Range structures
-//----------------------------------------------------------------------
static bool CompareDIEOffset(const DWARFDebugInfoEntry &die,
const dw_offset_t die_offset) {
return die.GetOffset() < die_offset;
}
-//----------------------------------------------------------------------
// GetDIE()
//
// Get the DIE (Debug Information Entry) with the specified offset by first
// checking if the DIE is contained within this compile unit and grabbing the
// DIE from this compile unit. Otherwise we grab the DIE from the DWARF file.
-//----------------------------------------------------------------------
DWARFDIE
DWARFUnit::GetDIE(dw_offset_t die_offset) {
if (die_offset != DW_INVALID_OFFSET) {
@@ -608,28 +470,26 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) {
if (die_offset == (*pos).GetOffset())
return DWARFDIE(this, &(*pos));
}
- } else {
- // Don't specify the compile unit offset as we don't know it because the
- // DIE belongs to
- // a different compile unit in the same symbol file.
- return m_dwarf->DebugInfo()->GetDIEForDIEOffset(die_offset);
- }
+ } else
+ GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+ "GetDIE for DIE 0x%" PRIx32 " is outside of its CU 0x%" PRIx32,
+ die_offset, GetOffset());
}
return DWARFDIE(); // Not found
}
+DWARFUnit &DWARFUnit::GetNonSkeletonUnit() {
+ if (SymbolFileDWARFDwo *dwo = GetDwoSymbolFile())
+ return *dwo->GetCompileUnit();
+ return *this;
+}
+
uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) {
if (cu)
return cu->GetAddressByteSize();
return DWARFUnit::GetDefaultAddressSize();
}
-bool DWARFUnit::IsDWARF64(const DWARFUnit *cu) {
- if (cu)
- return cu->IsDWARF64();
- return false;
-}
-
uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; }
void *DWARFUnit::GetUserData() const { return m_user_data; }
@@ -660,8 +520,6 @@ bool DWARFUnit::Supports_unnamed_objc_bitfields() {
// info
}
-SymbolFileDWARF *DWARFUnit::GetSymbolFileDWARF() const { return m_dwarf; }
-
void DWARFUnit::ParseProducerInfo() {
m_producer_version_major = UINT32_MAX;
m_producer_version_minor = UINT32_MAX;
@@ -671,7 +529,7 @@ void DWARFUnit::ParseProducerInfo() {
if (die) {
const char *producer_cstr =
- die->GetAttributeValueAsString(m_dwarf, this, DW_AT_producer, NULL);
+ die->GetAttributeValueAsString(this, DW_AT_producer, nullptr);
if (producer_cstr) {
RegularExpression llvm_gcc_regex(
llvm::StringRef("^4\\.[012]\\.[01] \\(Based on Apple "
@@ -748,7 +606,7 @@ LanguageType DWARFUnit::GetLanguageType() {
const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
if (die)
m_language_type = LanguageTypeFromDWARF(
- die->GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_language, 0));
+ die->GetAttributeValueAsUnsigned(this, DW_AT_language, 0));
return m_language_type;
}
@@ -757,8 +615,8 @@ bool DWARFUnit::GetIsOptimized() {
const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
if (die) {
m_is_optimized = eLazyBoolNo;
- if (die->GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_APPLE_optimized,
- 0) == 1) {
+ if (die->GetAttributeValueAsUnsigned(this, DW_AT_APPLE_optimized, 0) ==
+ 1) {
m_is_optimized = eLazyBoolYes;
}
}
@@ -766,40 +624,255 @@ bool DWARFUnit::GetIsOptimized() {
return m_is_optimized == eLazyBoolYes;
}
+FileSpec::Style DWARFUnit::GetPathStyle() {
+ if (!m_comp_dir)
+ ComputeCompDirAndGuessPathStyle();
+ return m_comp_dir->GetPathStyle();
+}
+
+const FileSpec &DWARFUnit::GetCompilationDirectory() {
+ if (!m_comp_dir)
+ ComputeCompDirAndGuessPathStyle();
+ return *m_comp_dir;
+}
+
+const FileSpec &DWARFUnit::GetAbsolutePath() {
+ if (!m_file_spec)
+ ComputeAbsolutePath();
+ return *m_file_spec;
+}
+
+FileSpec DWARFUnit::GetFile(size_t file_idx) {
+ return m_dwarf.GetFile(*this, file_idx);
+}
+
+// DWARF2/3 suggests the form hostname:pathname for compilation directory.
+// Remove the host part if present.
+static llvm::StringRef
+removeHostnameFromPathname(llvm::StringRef path_from_dwarf) {
+ llvm::StringRef host, path;
+ std::tie(host, path) = path_from_dwarf.split(':');
+
+ if (host.contains('/'))
+ return path_from_dwarf;
+
+ // check whether we have a windows path, and so the first character is a
+ // drive-letter not a hostname.
+ if (host.size() == 1 && llvm::isAlpha(host[0]) && path.startswith("\\"))
+ return path_from_dwarf;
+
+ return path;
+}
+
+static FileSpec resolveCompDir(const FileSpec &path) {
+ bool is_symlink = SymbolFileDWARF::GetSymlinkPaths().FindFileIndex(
+ 0, path, /*full*/ true) != UINT32_MAX;
+
+ if (!is_symlink)
+ return path;
+
+ namespace fs = llvm::sys::fs;
+ if (fs::get_file_type(path.GetPath(), false) != fs::file_type::symlink_file)
+ return path;
+
+ FileSpec resolved_symlink;
+ const auto error = FileSystem::Instance().Readlink(path, resolved_symlink);
+ if (error.Success())
+ return resolved_symlink;
+
+ return path;
+}
+
+void DWARFUnit::ComputeCompDirAndGuessPathStyle() {
+ m_comp_dir = FileSpec();
+ const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
+ if (!die)
+ return;
+
+ llvm::StringRef comp_dir = removeHostnameFromPathname(
+ die->GetAttributeValueAsString(this, DW_AT_comp_dir, nullptr));
+ if (!comp_dir.empty()) {
+ FileSpec::Style comp_dir_style =
+ FileSpec::GuessPathStyle(comp_dir).getValueOr(FileSpec::Style::native);
+ m_comp_dir = resolveCompDir(FileSpec(comp_dir, comp_dir_style));
+ } else {
+ // Try to detect the style based on the DW_AT_name attribute, but just store
+ // the detected style in the m_comp_dir field.
+ const char *name =
+ die->GetAttributeValueAsString(this, DW_AT_name, nullptr);
+ m_comp_dir = FileSpec(
+ "", FileSpec::GuessPathStyle(name).getValueOr(FileSpec::Style::native));
+ }
+}
+
+void DWARFUnit::ComputeAbsolutePath() {
+ m_file_spec = FileSpec();
+ const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
+ if (!die)
+ return;
+
+ m_file_spec =
+ FileSpec(die->GetAttributeValueAsString(this, DW_AT_name, nullptr),
+ GetPathStyle());
+
+ if (m_file_spec->IsRelative())
+ m_file_spec->MakeAbsolute(GetCompilationDirectory());
+}
+
SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile() const {
return m_dwo_symbol_file.get();
}
-dw_offset_t DWARFUnit::GetBaseObjOffset() const { return m_base_obj_offset; }
-
const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() {
- if (m_func_aranges_ap.get() == NULL) {
- m_func_aranges_ap.reset(new DWARFDebugAranges());
- Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
-
- if (log) {
- m_dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "DWARFUnit::GetFunctionAranges() for compile unit at "
- ".debug_info[0x%8.8x]",
- GetOffset());
- }
+ if (m_func_aranges_up == nullptr) {
+ m_func_aranges_up.reset(new DWARFDebugAranges());
const DWARFDebugInfoEntry *die = DIEPtr();
if (die)
- die->BuildFunctionAddressRangeTable(m_dwarf, this,
- m_func_aranges_ap.get());
+ die->BuildFunctionAddressRangeTable(this, m_func_aranges_up.get());
if (m_dwo_symbol_file) {
DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit();
const DWARFDebugInfoEntry *dwo_die = dwo_cu->DIEPtr();
if (dwo_die)
- dwo_die->BuildFunctionAddressRangeTable(m_dwo_symbol_file.get(), dwo_cu,
- m_func_aranges_ap.get());
+ dwo_die->BuildFunctionAddressRangeTable(dwo_cu,
+ m_func_aranges_up.get());
}
const bool minimize = false;
- m_func_aranges_ap->Sort(minimize);
+ m_func_aranges_up->Sort(minimize);
+ }
+ return *m_func_aranges_up;
+}
+
+llvm::Expected<DWARFUnitHeader>
+DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section,
+ lldb::offset_t *offset_ptr) {
+ DWARFUnitHeader header;
+ header.m_offset = *offset_ptr;
+ header.m_length = data.GetDWARFInitialLength(offset_ptr);
+ header.m_version = data.GetU16(offset_ptr);
+ if (header.m_version == 5) {
+ header.m_unit_type = data.GetU8(offset_ptr);
+ header.m_addr_size = data.GetU8(offset_ptr);
+ header.m_abbr_offset = data.GetDWARFOffset(offset_ptr);
+ if (header.m_unit_type == llvm::dwarf::DW_UT_skeleton)
+ header.m_dwo_id = data.GetU64(offset_ptr);
+ } else {
+ header.m_abbr_offset = data.GetDWARFOffset(offset_ptr);
+ header.m_addr_size = data.GetU8(offset_ptr);
+ header.m_unit_type =
+ section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile;
+ }
+
+ if (header.IsTypeUnit()) {
+ header.m_type_hash = data.GetU64(offset_ptr);
+ header.m_type_offset = data.GetDWARFOffset(offset_ptr);
+ }
+
+ bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1);
+ bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version);
+ bool addr_size_OK = (header.m_addr_size == 4) || (header.m_addr_size == 8);
+ bool type_offset_OK =
+ !header.IsTypeUnit() || (header.m_type_offset <= header.GetLength());
+
+ if (!length_OK)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "Invalid unit length");
+ if (!version_OK)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "Unsupported unit version");
+ if (!addr_size_OK)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "Invalid unit address size");
+ if (!type_offset_OK)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "Type offset out of range");
+
+ return header;
+}
+
+llvm::Expected<DWARFUnitSP>
+DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid,
+ const DWARFDataExtractor &debug_info,
+ DIERef::Section section, lldb::offset_t *offset_ptr) {
+ assert(debug_info.ValidOffset(*offset_ptr));
+
+ auto expected_header =
+ DWARFUnitHeader::extract(debug_info, section, offset_ptr);
+ if (!expected_header)
+ return expected_header.takeError();
+
+ const DWARFDebugAbbrev *abbr = dwarf.DebugAbbrev();
+ if (!abbr)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "No debug_abbrev data");
+
+ bool abbr_offset_OK =
+ dwarf.GetDWARFContext().getOrLoadAbbrevData().ValidOffset(
+ expected_header->GetAbbrOffset());
+ if (!abbr_offset_OK)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "Abbreviation offset for unit is not valid");
+
+ const DWARFAbbreviationDeclarationSet *abbrevs =
+ abbr->GetAbbreviationDeclarationSet(expected_header->GetAbbrOffset());
+ if (!abbrevs)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "No abbrev exists at the specified offset.");
+
+ if (expected_header->IsTypeUnit())
+ return DWARFUnitSP(
+ new DWARFTypeUnit(dwarf, uid, *expected_header, *abbrevs, section));
+ return DWARFUnitSP(
+ new DWARFCompileUnit(dwarf, uid, *expected_header, *abbrevs, section));
+}
+
+const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const {
+ return m_section == DIERef::Section::DebugTypes
+ ? m_dwarf.GetDWARFContext().getOrLoadDebugTypesData()
+ : m_dwarf.GetDWARFContext().getOrLoadDebugInfoData();
+}
+
+uint32_t DWARFUnit::GetHeaderByteSize() const {
+ switch (m_header.GetUnitType()) {
+ case llvm::dwarf::DW_UT_compile:
+ case llvm::dwarf::DW_UT_partial:
+ return GetVersion() < 5 ? 11 : 12;
+ case llvm::dwarf::DW_UT_skeleton:
+ case llvm::dwarf::DW_UT_split_compile:
+ return 20;
+ case llvm::dwarf::DW_UT_type:
+ case llvm::dwarf::DW_UT_split_type:
+ return GetVersion() < 5 ? 23 : 24;
}
- return *m_func_aranges_ap.get();
+ llvm_unreachable("invalid UnitType.");
+}
+
+llvm::Expected<DWARFRangeList>
+DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) const {
+ const DWARFDebugRangesBase *debug_ranges;
+ llvm::StringRef section;
+ if (GetVersion() <= 4) {
+ debug_ranges = m_dwarf.GetDebugRanges();
+ section = "debug_ranges";
+ } else {
+ debug_ranges = m_dwarf.GetDebugRngLists();
+ section = "debug_rnglists";
+ }
+ if (!debug_ranges)
+ return llvm::make_error<llvm::object::GenericBinaryError>("No " + section +
+ " section");
+
+ DWARFRangeList ranges;
+ debug_ranges->FindRanges(this, offset, ranges);
+ return ranges;
}
+llvm::Expected<DWARFRangeList>
+DWARFUnit::FindRnglistFromIndex(uint32_t index) const {
+ const DWARFDebugRangesBase *debug_rnglists = m_dwarf.GetDebugRngLists();
+ if (!debug_rnglists)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "No debug_rnglists section");
+ return FindRnglistFromOffset(debug_rnglists->GetOffset(index));
+}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 178c894686ee..8aa1e449f3ed 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -1,9 +1,8 @@
//===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -32,11 +31,52 @@ enum DWARFProducer {
eProcucerOther
};
-class DWARFUnit {
+/// Base class describing the header of any kind of "unit." Some information
+/// is specific to certain unit types. We separate this class out so we can
+/// parse the header before deciding what specific kind of unit to construct.
+class DWARFUnitHeader {
+ dw_offset_t m_offset = 0;
+ dw_offset_t m_length = 0;
+ uint16_t m_version = 0;
+ dw_offset_t m_abbr_offset = 0;
+ uint8_t m_unit_type = 0;
+ uint8_t m_addr_size = 0;
+
+ uint64_t m_type_hash = 0;
+ uint32_t m_type_offset = 0;
+
+ uint64_t m_dwo_id = 0;
+
+ DWARFUnitHeader() = default;
+
+public:
+ dw_offset_t GetOffset() const { return m_offset; }
+ uint16_t GetVersion() const { return m_version; }
+ uint16_t GetAddressByteSize() const { return m_addr_size; }
+ dw_offset_t GetLength() const { return m_length; }
+ dw_offset_t GetAbbrOffset() const { return m_abbr_offset; }
+ uint8_t GetUnitType() const { return m_unit_type; }
+ uint64_t GetTypeHash() const { return m_type_hash; }
+ dw_offset_t GetTypeOffset() const { return m_type_offset; }
+ bool IsTypeUnit() const {
+ return m_unit_type == DW_UT_type || m_unit_type == DW_UT_split_type;
+ }
+ uint32_t GetNextUnitOffset() const { return m_offset + m_length + 4; }
+
+ static llvm::Expected<DWARFUnitHeader>
+ extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section,
+ lldb::offset_t *offset_ptr);
+};
+
+class DWARFUnit : public lldb_private::UserID {
using die_iterator_range =
llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>;
public:
+ static llvm::Expected<DWARFUnitSP>
+ extract(SymbolFileDWARF &dwarf2Data, lldb::user_id_t uid,
+ const lldb_private::DWARFDataExtractor &debug_info,
+ DIERef::Section section, lldb::offset_t *offset_ptr);
virtual ~DWARFUnit();
void ExtractUnitDIEIfNeeded();
@@ -46,7 +86,7 @@ public:
DWARFUnit *m_cu;
public:
bool m_clear_dies = false;
- ScopedExtractDIEs(DWARFUnit *cu);
+ ScopedExtractDIEs(DWARFUnit &cu);
~ScopedExtractDIEs();
DISALLOW_COPY_AND_ASSIGN(ScopedExtractDIEs);
ScopedExtractDIEs(ScopedExtractDIEs &&rhs);
@@ -55,69 +95,61 @@ public:
ScopedExtractDIEs ExtractDIEsScoped();
DWARFDIE LookupAddress(const dw_addr_t address);
- size_t AppendDIEsWithTag(const dw_tag_t tag,
- DWARFDIECollection &matching_dies,
+ size_t AppendDIEsWithTag(const dw_tag_t tag, std::vector<DWARFDIE> &dies,
uint32_t depth = UINT32_MAX) const;
bool Verify(lldb_private::Stream *s) const;
virtual void Dump(lldb_private::Stream *s) const = 0;
- //------------------------------------------------------------------
/// Get the data that contains the DIE information for this unit.
///
/// This will return the correct bytes that contain the data for
/// this DWARFUnit. It could be .debug_info or .debug_types
/// depending on where the data for this unit originates.
///
- /// @return
+ /// \return
/// The correct data for the DIE information in this unit.
- //------------------------------------------------------------------
- virtual const lldb_private::DWARFDataExtractor &GetData() const = 0;
- //------------------------------------------------------------------
- /// Get the size in bytes of the compile unit header.
+ const lldb_private::DWARFDataExtractor &GetData() const;
+
+ /// Get the size in bytes of the unit header.
///
- /// @return
- /// Byte size of the compile unit header
- //------------------------------------------------------------------
- virtual uint32_t GetHeaderByteSize() const = 0;
+ /// \return
+ /// Byte size of the unit header
+ uint32_t GetHeaderByteSize() const;
+
// Offset of the initial length field.
- dw_offset_t GetOffset() const { return m_offset; }
- lldb::user_id_t GetID() const;
- //------------------------------------------------------------------
+ dw_offset_t GetOffset() const { return m_header.GetOffset(); }
/// Get the size in bytes of the length field in the header.
///
- /// In DWARF32 this is just 4 bytes, and DWARF64 it is 12 where 4
- /// are 0xFFFFFFFF followed by the actual 64 bit length.
+ /// In DWARF32 this is just 4 bytes
///
- /// @return
+ /// \return
/// Byte size of the compile unit header length field
- //------------------------------------------------------------------
- size_t GetLengthByteSize() const { return IsDWARF64() ? 12 : 4; }
-
+ size_t GetLengthByteSize() const { return 4; }
+
bool ContainsDIEOffset(dw_offset_t die_offset) const {
return die_offset >= GetFirstDIEOffset() &&
- die_offset < GetNextCompileUnitOffset();
+ die_offset < GetNextUnitOffset();
}
dw_offset_t GetFirstDIEOffset() const {
- return m_offset + GetHeaderByteSize();
+ return GetOffset() + GetHeaderByteSize();
}
- dw_offset_t GetNextCompileUnitOffset() const;
+ dw_offset_t GetNextUnitOffset() const { return m_header.GetNextUnitOffset(); }
// Size of the CU data (without initial length and without header).
size_t GetDebugInfoSize() const;
// Size of the CU data incl. header but without initial length.
- uint32_t GetLength() const { return m_length; }
- uint16_t GetVersion() const { return m_version; }
+ uint32_t GetLength() const { return m_header.GetLength(); }
+ uint16_t GetVersion() const { return m_header.GetVersion(); }
const DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
dw_offset_t GetAbbrevOffset() const;
- uint8_t GetAddressByteSize() const { return m_addr_size; }
- dw_addr_t GetBaseAddress() const { return m_base_addr; }
+ uint8_t GetAddressByteSize() const { return m_header.GetAddressByteSize(); }
dw_addr_t GetAddrBase() const { return m_addr_base; }
+ dw_addr_t GetBaseAddress() const { return m_base_addr; }
+ dw_offset_t GetLineTableOffset();
dw_addr_t GetRangesBase() const { return m_ranges_base; }
dw_addr_t GetStrOffsetsBase() const { return m_str_offsets_base; }
void SetAddrBase(dw_addr_t addr_base);
void SetRangesBase(dw_addr_t ranges_base);
- void SetBaseObjOffset(dw_offset_t base_obj_offset);
void SetStrOffsetsBase(dw_offset_t str_offsets_base);
- void BuildAddressRangeTable(SymbolFileDWARF *dwarf,
- DWARFDebugAranges *debug_aranges);
+ virtual void BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) = 0;
lldb::ByteOrder GetByteOrder() const;
@@ -125,8 +157,6 @@ public:
const DWARFDebugAranges &GetFunctionAranges();
- DWARFFormValue::FixedFormSizes GetFixedFormSizes();
-
void SetBaseAddress(dw_addr_t base_addr);
DWARFBaseDIE GetUnitDIEOnly() { return DWARFDIE(this, GetUnitDIEPtrOnly()); }
@@ -135,9 +165,9 @@ public:
DWARFDIE GetDIE(dw_offset_t die_offset);
- static uint8_t GetAddressByteSize(const DWARFUnit *cu);
+ DWARFUnit &GetNonSkeletonUnit();
- static bool IsDWARF64(const DWARFUnit *cu);
+ static uint8_t GetAddressByteSize(const DWARFUnit *cu);
static uint8_t GetDefaultAddressSize();
@@ -151,7 +181,7 @@ public:
bool Supports_unnamed_objc_bitfields();
- SymbolFileDWARF *GetSymbolFileDWARF() const;
+ SymbolFileDWARF &GetSymbolFileDWARF() const { return m_dwarf; }
DWARFProducer GetProducer();
@@ -165,24 +195,65 @@ public:
lldb::LanguageType GetLanguageType();
- bool IsDWARF64() const { return m_is_dwarf64; }
-
bool GetIsOptimized();
- SymbolFileDWARFDwo *GetDwoSymbolFile() const;
+ const lldb_private::FileSpec &GetCompilationDirectory();
+ const lldb_private::FileSpec &GetAbsolutePath();
+ lldb_private::FileSpec GetFile(size_t file_idx);
+ lldb_private::FileSpec::Style GetPathStyle();
- dw_offset_t GetBaseObjOffset() const;
+ SymbolFileDWARFDwo *GetDwoSymbolFile() const;
die_iterator_range dies() {
ExtractDIEsIfNeeded();
return die_iterator_range(m_die_array.begin(), m_die_array.end());
}
+ DIERef::Section GetDebugSection() const { return m_section; }
+
+ uint8_t GetUnitType() const { return m_header.GetUnitType(); }
+ bool IsTypeUnit() const { return m_header.IsTypeUnit(); }
+
+ /// Return a list of address ranges resulting from a (possibly encoded)
+ /// range list starting at a given offset in the appropriate ranges section.
+ llvm::Expected<DWARFRangeList> FindRnglistFromOffset(dw_offset_t offset) const;
+
+ /// Return a list of address ranges retrieved from an encoded range
+ /// list whose offset is found via a table lookup given an index (DWARF v5
+ /// and later).
+ llvm::Expected<DWARFRangeList> FindRnglistFromIndex(uint32_t index) const;
+
protected:
- DWARFUnit(SymbolFileDWARF *dwarf);
+ DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
+ const DWARFUnitHeader &header,
+ const DWARFAbbreviationDeclarationSet &abbrevs,
+ DIERef::Section section);
+
+ llvm::Error ExtractHeader(SymbolFileDWARF &dwarf,
+ const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
+
+ // Get the DWARF unit DWARF debug information entry. Parse the single DIE
+ // if needed.
+ const DWARFDebugInfoEntry *GetUnitDIEPtrOnly() {
+ ExtractUnitDIEIfNeeded();
+ // m_first_die_mutex is not required as m_first_die is never cleared.
+ if (!m_first_die)
+ return NULL;
+ return &m_first_die;
+ }
+
+ // Get all DWARF debug informration entries. Parse all DIEs if needed.
+ const DWARFDebugInfoEntry *DIEPtr() {
+ ExtractDIEsIfNeeded();
+ if (m_die_array.empty())
+ return NULL;
+ return &m_die_array[0];
+ }
- SymbolFileDWARF *m_dwarf = nullptr;
+ SymbolFileDWARF &m_dwarf;
std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
+ DWARFUnitHeader m_header;
const DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr;
void *m_user_data = nullptr;
// The compile unit debug information entry item
@@ -200,54 +271,34 @@ protected:
llvm::sys::RWMutex m_first_die_mutex;
// A table similar to the .debug_aranges table, but this one points to the
// exact DW_TAG_subprogram DIEs
- std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap;
+ std::unique_ptr<DWARFDebugAranges> m_func_aranges_up;
dw_addr_t m_base_addr = 0;
- dw_offset_t m_length = 0;
- uint16_t m_version = 0;
- uint8_t m_addr_size = 0;
- uint8_t m_unit_type = 0;
- uint64_t m_dwo_id = 0;
DWARFProducer m_producer = eProducerInvalid;
uint32_t m_producer_version_major = 0;
uint32_t m_producer_version_minor = 0;
uint32_t m_producer_version_update = 0;
lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown;
- bool m_is_dwarf64 = false;
lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate;
+ llvm::Optional<lldb_private::FileSpec> m_comp_dir;
+ llvm::Optional<lldb_private::FileSpec> m_file_spec;
dw_addr_t m_addr_base = 0; // Value of DW_AT_addr_base
dw_addr_t m_ranges_base = 0; // Value of DW_AT_ranges_base
- // If this is a dwo compile unit this is the offset of the base compile unit
- // in the main object file
- dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
+
+ /// Value of DW_AT_stmt_list.
+ dw_offset_t m_line_table_offset = DW_INVALID_OFFSET;
+
dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base.
- // Offset of the initial length field.
- dw_offset_t m_offset;
+ const DIERef::Section m_section;
private:
void ParseProducerInfo();
void ExtractDIEsRWLocked();
void ClearDIEsRWLocked();
- // Get the DWARF unit DWARF debug informration entry. Parse the single DIE
- // if needed.
- const DWARFDebugInfoEntry *GetUnitDIEPtrOnly() {
- ExtractUnitDIEIfNeeded();
- // m_first_die_mutex is not required as m_first_die is never cleared.
- if (!m_first_die)
- return NULL;
- return &m_first_die;
- }
-
- // Get all DWARF debug informration entries. Parse all DIEs if needed.
- const DWARFDebugInfoEntry *DIEPtr() {
- ExtractDIEsIfNeeded();
- if (m_die_array.empty())
- return NULL;
- return &m_die_array[0];
- }
-
void AddUnitDIE(const DWARFDebugInfoEntry &cu_die);
- void ExtractDIEsEndCheck(lldb::offset_t offset) const;
+
+ void ComputeCompDirAndGuessPathStyle();
+ void ComputeAbsolutePath();
DISALLOW_COPY_AND_ASSIGN(DWARFUnit);
};
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index c043272f8a3e..9746ad76c930 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -1,9 +1,8 @@
//===-- DebugNamesDWARFIndex.cpp -------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -17,13 +16,6 @@
using namespace lldb_private;
using namespace lldb;
-static llvm::DWARFDataExtractor ToLLVM(const DWARFDataExtractor &data) {
- return llvm::DWARFDataExtractor(
- llvm::StringRef(reinterpret_cast<const char *>(data.GetDataStart()),
- data.GetByteSize()),
- data.GetByteOrder() == eByteOrderLittle, data.GetAddressByteSize());
-}
-
llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names,
DWARFDataExtractor debug_str,
@@ -32,8 +24,8 @@ DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names,
return llvm::make_error<llvm::StringError>("debug info null",
llvm::inconvertibleErrorCode());
}
- auto index_up =
- llvm::make_unique<DebugNames>(ToLLVM(debug_names), ToLLVM(debug_str));
+ auto index_up = llvm::make_unique<DebugNames>(debug_names.GetAsLLVM(),
+ debug_str.GetAsLLVM());
if (llvm::Error E = index_up->extract())
return std::move(E);
@@ -51,31 +43,33 @@ DebugNamesDWARFIndex::GetUnits(const DebugNames &debug_names) {
return result;
}
-DIERef DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) {
+llvm::Optional<DIERef>
+DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) {
llvm::Optional<uint64_t> cu_offset = entry.getCUOffset();
if (!cu_offset)
- return DIERef();
+ return llvm::None;
- DWARFUnit *cu = m_debug_info.GetCompileUnit(*cu_offset);
+ DWARFUnit *cu = m_debug_info.GetUnitAtOffset(DIERef::Section::DebugInfo, *cu_offset);
if (!cu)
- return DIERef();
+ return llvm::None;
// This initializes the DWO symbol file. It's not possible for
// GetDwoSymbolFile to call this automatically because of mutual recursion
// between this and DWARFDebugInfoEntry::GetAttributeValue.
cu->ExtractUnitDIEIfNeeded();
- uint64_t die_bias = cu->GetDwoSymbolFile() ? 0 : *cu_offset;
+ cu = &cu->GetNonSkeletonUnit();
if (llvm::Optional<uint64_t> die_offset = entry.getDIEUnitOffset())
- return DIERef(*cu_offset, die_bias + *die_offset);
+ return DIERef(cu->GetSymbolFileDWARF().GetDwoNum(),
+ DIERef::Section::DebugInfo, cu->GetOffset() + *die_offset);
- return DIERef();
+ return llvm::None;
}
void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry,
DIEArray &offsets) {
- if (DIERef ref = ToDIERef(entry))
- offsets.push_back(ref);
+ if (llvm::Optional<DIERef> ref = ToDIERef(entry))
+ offsets.push_back(*ref);
}
void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error,
@@ -161,27 +155,27 @@ void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name,
entry.tag() != DW_TAG_class_type)
continue;
- DIERef ref = ToDIERef(entry);
+ llvm::Optional<DIERef> ref = ToDIERef(entry);
if (!ref)
continue;
- DWARFUnit *cu = m_debug_info.GetCompileUnit(ref.cu_offset);
+ DWARFUnit *cu = m_debug_info.GetUnit(*ref);
if (!cu || !cu->Supports_DW_AT_APPLE_objc_complete_type()) {
- incomplete_types.push_back(ref);
+ incomplete_types.push_back(*ref);
continue;
}
// FIXME: We should return DWARFDIEs so we don't have to resolve it twice.
- DWARFDIE die = m_debug_info.GetDIE(ref);
+ DWARFDIE die = m_debug_info.GetDIE(*ref);
if (!die)
continue;
if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) {
// If we find the complete version we're done.
- offsets.push_back(ref);
+ offsets.push_back(*ref);
return;
} else {
- incomplete_types.push_back(ref);
+ incomplete_types.push_back(*ref);
}
}
@@ -221,12 +215,12 @@ void DebugNamesDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
}
void DebugNamesDWARFIndex::GetFunctions(
- ConstString name, DWARFDebugInfo &info,
+ ConstString name, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
std::vector<DWARFDIE> &dies) {
std::vector<DWARFDIE> v;
- m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, v);
+ m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask, v);
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(name.GetStringRef())) {
@@ -234,8 +228,8 @@ void DebugNamesDWARFIndex::GetFunctions(
if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
continue;
- if (DIERef ref = ToDIERef(entry))
- ProcessFunctionDIE(name.GetStringRef(), ref, info, parent_decl_ctx,
+ if (llvm::Optional<DIERef> ref = ToDIERef(entry))
+ ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx,
name_type_mask, v);
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
index 30423c7ca2a2..dca25496373f 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
@@ -1,9 +1,8 @@
//===-- DebugNamesDWARFIndex.h ---------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -35,15 +34,14 @@ public:
void GetTypes(ConstString name, DIEArray &offsets) override;
void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
void GetNamespaces(ConstString name, DIEArray &offsets) override;
- void GetFunctions(ConstString name, DWARFDebugInfo &info,
+ void GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
uint32_t name_type_mask,
std::vector<DWARFDIE> &dies) override;
void GetFunctions(const RegularExpression &regex,
DIEArray &offsets) override;
- void ReportInvalidDIEOffset(dw_offset_t offset,
- llvm::StringRef name) override {}
+ void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {}
void Dump(Stream &s) override;
private:
@@ -68,7 +66,7 @@ private:
std::unique_ptr<DebugNames> m_debug_names_up;
ManualDWARFIndex m_fallback;
- DIERef ToDIERef(const DebugNames::Entry &entry);
+ llvm::Optional<DIERef> ToDIERef(const DebugNames::Entry &entry);
void Append(const DebugNames::Entry &entry, DIEArray &offsets);
static void MaybeLogLookupError(llvm::Error error,
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index f83ba6663dfc..62b0ad37a9fc 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -1,9 +1,8 @@
//===-- HashedNameToDIE.cpp -------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -14,8 +13,7 @@ void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
DIEArray &die_offsets) {
const size_t count = die_info_array.size();
for (size_t i = 0; i < count; ++i)
- die_offsets.emplace_back(die_info_array[i].cu_offset,
- die_info_array[i].offset);
+ die_offsets.emplace_back(die_info_array[i]);
}
void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
@@ -34,8 +32,7 @@ void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
}
if (tag_matches)
- die_offsets.emplace_back(die_info_array[i].cu_offset,
- die_info_array[i].offset);
+ die_offsets.emplace_back(die_info_array[i]);
}
}
}
@@ -59,8 +56,7 @@ void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
}
if (tag_matches)
- die_offsets.emplace_back(die_info_array[i].cu_offset,
- die_info_array[i].offset);
+ die_offsets.emplace_back(die_info_array[i]);
}
}
}
@@ -78,17 +74,14 @@ void DWARFMappedHash::ExtractClassOrStructDIEArray(
// We found the one true definition for this class, so only return
// that
die_offsets.clear();
- die_offsets.emplace_back(die_info_array[i].cu_offset,
- die_info_array[i].offset);
+ die_offsets.emplace_back(die_info_array[i]);
return;
} else {
// Put the one true definition as the first entry so it matches first
- die_offsets.emplace(die_offsets.begin(), die_info_array[i].cu_offset,
- die_info_array[i].offset);
+ die_offsets.emplace(die_offsets.begin(), die_info_array[i]);
}
} else {
- die_offsets.emplace_back(die_info_array[i].cu_offset,
- die_info_array[i].offset);
+ die_offsets.emplace_back(die_info_array[i]);
}
}
}
@@ -100,8 +93,7 @@ void DWARFMappedHash::ExtractTypesFromDIEArray(
const size_t count = die_info_array.size();
for (size_t i = 0; i < count; ++i) {
if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value)
- die_offsets.emplace_back(die_info_array[i].cu_offset,
- die_info_array[i].offset);
+ die_offsets.emplace_back(die_info_array[i]);
}
}
@@ -125,13 +117,9 @@ const char *DWARFMappedHash::GetAtomTypeName(uint16_t atom) {
return "<invalid>";
}
-DWARFMappedHash::DIEInfo::DIEInfo()
- : cu_offset(DW_INVALID_OFFSET), offset(DW_INVALID_OFFSET), tag(0),
- type_flags(0), qualified_name_hash(0) {}
-
-DWARFMappedHash::DIEInfo::DIEInfo(dw_offset_t c, dw_offset_t o, dw_tag_t t,
- uint32_t f, uint32_t h)
- : cu_offset(c), offset(o), tag(t), type_flags(f), qualified_name_hash(h) {}
+DWARFMappedHash::DIEInfo::DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f,
+ uint32_t h)
+ : die_offset(o), tag(t), type_flags(f), qualified_name_hash(h) {}
DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset)
: die_base_offset(_die_base_offset), atoms(), atom_mask(0),
@@ -167,6 +155,7 @@ void DWARFMappedHash::Prologue::AppendAtom(AtomType type, dw_form_t form) {
case DW_FORM_ref_sig8:
llvm_unreachable("Unhandled atom form");
+ case DW_FORM_addrx:
case DW_FORM_string:
case DW_FORM_block:
case DW_FORM_block1:
@@ -271,14 +260,14 @@ bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data,
return false;
for (size_t i = 0; i < num_atoms; ++i) {
- DWARFFormValue form_value(NULL, header_data.atoms[i].form);
+ DWARFFormValue form_value(nullptr, header_data.atoms[i].form);
if (!form_value.ExtractValue(data, offset_ptr))
return false;
switch (header_data.atoms[i].type) {
case eAtomTypeDIEOffset: // DIE offset, check form for encoding
- hash_data.offset =
+ hash_data.die_offset =
DWARFFormValue::IsDataForm(form_value.Form())
? form_value.Unsigned()
: form_value.Reference(header_data.die_base_offset);
@@ -301,50 +290,7 @@ bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data,
break;
}
}
- return true;
-}
-
-void DWARFMappedHash::Header::Dump(lldb_private::Stream &strm,
- const DIEInfo &hash_data) const {
- const size_t num_atoms = header_data.atoms.size();
- for (size_t i = 0; i < num_atoms; ++i) {
- if (i > 0)
- strm.PutCString(", ");
-
- DWARFFormValue form_value(NULL, header_data.atoms[i].form);
- switch (header_data.atoms[i].type) {
- case eAtomTypeDIEOffset: // DIE offset, check form for encoding
- strm.Printf("{0x%8.8x}", hash_data.offset);
- break;
-
- case eAtomTypeTag: // DW_TAG value for the DIE
- {
- const char *tag_cstr = lldb_private::DW_TAG_value_to_name(hash_data.tag);
- if (tag_cstr)
- strm.PutCString(tag_cstr);
- else
- strm.Printf("DW_TAG_(0x%4.4x)", hash_data.tag);
- } break;
-
- case eAtomTypeTypeFlags: // Flags from enum TypeFlags
- strm.Printf("0x%2.2x", hash_data.type_flags);
- if (hash_data.type_flags) {
- strm.PutCString(" (");
- if (hash_data.type_flags & eTypeFlagClassIsImplementation)
- strm.PutCString(" implementation");
- strm.PutCString(" )");
- }
- break;
-
- case eAtomTypeQualNameHash: // Flags from enum TypeFlags
- strm.Printf("0x%8.8x", hash_data.qualified_name_hash);
- break;
-
- default:
- strm.Printf("AtomType(0x%x)", header_data.atoms[i].type);
- break;
- }
- }
+ return hash_data.die_offset != DW_INVALID_OFFSET;
}
DWARFMappedHash::MemoryTable::MemoryTable(
@@ -391,7 +337,7 @@ DWARFMappedHash::MemoryTable::GetHashDataForName(
// There definitely should be a string for this string offset, if there
// isn't, there is something wrong, return and error
const char *strp_cstr = m_string_table.PeekCStr(pair.key);
- if (strp_cstr == NULL) {
+ if (strp_cstr == nullptr) {
*hash_data_offset_ptr = UINT32_MAX;
return eResultError;
}
@@ -458,7 +404,7 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
// There definitely should be a string for this string offset, if there
// isn't, there is something wrong, return and error
const char *strp_cstr = m_string_table.PeekCStr(pair.key);
- if (strp_cstr == NULL)
+ if (strp_cstr == nullptr)
return eResultError;
const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
@@ -556,10 +502,10 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange(
for (uint32_t i = 0; i < count; ++i) {
DIEInfo die_info;
if (m_header.Read(m_data, &hash_data_offset, die_info)) {
- if (die_info.offset == 0)
+ if (die_info.die_offset == 0)
done = true;
- if (die_offset_start <= die_info.offset &&
- die_info.offset < die_offset_end)
+ if (die_offset_start <= die_info.die_offset &&
+ die_info.die_offset < die_offset_end)
die_info_array.push_back(die_info);
}
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
index 17600df2edd4..a01612b59528 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -1,9 +1,8 @@
//===-- HashedNameToDIE.h ---------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -49,14 +48,21 @@ public:
};
struct DIEInfo {
- dw_offset_t cu_offset;
- dw_offset_t offset; // The DIE offset
- dw_tag_t tag;
- uint32_t type_flags; // Any flags for this DIEInfo
- uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name
-
- DIEInfo();
- DIEInfo(dw_offset_t c, dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
+ dw_offset_t die_offset = DW_INVALID_OFFSET;
+ dw_tag_t tag = 0;
+
+ /// Any flags for this DIEInfo
+ uint32_t type_flags = 0;
+
+ /// A 32 bit hash of the fully qualified name
+ uint32_t qualified_name_hash = 0;
+
+ DIEInfo() = default;
+ DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
+
+ explicit operator DIERef() const {
+ return DIERef(llvm::None, DIERef::Section::DebugInfo, die_offset);
+ }
};
struct Atom {
@@ -105,8 +111,6 @@ public:
bool Read(const lldb_private::DWARFDataExtractor &data,
lldb::offset_t *offset_ptr, DIEInfo &hash_data) const;
-
- void Dump(lldb_private::Stream &strm, const DIEInfo &hash_data) const;
};
// A class for reading and using a saved hash table from a block of data
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
index 0b06713f9543..8495016d4280 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
@@ -1,9 +1,8 @@
//===-- LogChannelDWARF.cpp ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -12,9 +11,6 @@
using namespace lldb_private;
static constexpr Log::Category g_categories[] = {
- {{"aranges"},
- {"log the parsing of .debug_aranges"},
- DWARF_LOG_DEBUG_ARANGES},
{{"comp"},
{"log insertions of object files into DWARF debug maps"},
DWARF_LOG_TYPE_COMPLETION},
@@ -26,12 +22,6 @@ static constexpr Log::Category g_categories[] = {
{{"map"},
{"log struct/unions/class type completions"},
DWARF_LOG_DEBUG_MAP},
- {{"pubnames"},
- {"log the parsing of .debug_pubnames"},
- DWARF_LOG_DEBUG_PUBNAMES},
- {{"pubtypes"},
- {"log the parsing of .debug_pubtypes"},
- DWARF_LOG_DEBUG_PUBTYPES},
};
Log::Channel LogChannelDWARF::g_channel(g_categories, DWARF_LOG_DEFAULT);
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
index 038e9b8c2b08..a89c686735d2 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
@@ -1,9 +1,8 @@
//===-- LogChannelDWARF.h ---------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -14,12 +13,9 @@
#define DWARF_LOG_DEBUG_INFO (1u << 1)
#define DWARF_LOG_DEBUG_LINE (1u << 2)
-#define DWARF_LOG_DEBUG_PUBNAMES (1u << 3)
-#define DWARF_LOG_DEBUG_PUBTYPES (1u << 4)
-#define DWARF_LOG_DEBUG_ARANGES (1u << 5)
-#define DWARF_LOG_LOOKUPS (1u << 6)
-#define DWARF_LOG_TYPE_COMPLETION (1u << 7)
-#define DWARF_LOG_DEBUG_MAP (1u << 8)
+#define DWARF_LOG_LOOKUPS (1u << 3)
+#define DWARF_LOG_TYPE_COMPLETION (1u << 4)
+#define DWARF_LOG_DEBUG_MAP (1u << 5)
#define DWARF_LOG_ALL (UINT32_MAX)
#define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO)
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
index 6438f02fe8ec..aff8b5d8c15f 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -1,9 +1,8 @@
//===-- ManualDWARFIndex.cpp -----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -33,9 +32,9 @@ void ManualDWARFIndex::Index() {
Timer scoped_timer(func_cat, "%p", static_cast<void *>(&debug_info));
std::vector<DWARFUnit *> units_to_index;
- units_to_index.reserve(debug_info.GetNumCompileUnits());
- for (size_t U = 0; U < debug_info.GetNumCompileUnits(); ++U) {
- DWARFUnit *unit = debug_info.GetCompileUnitAtIndex(U);
+ units_to_index.reserve(debug_info.GetNumUnits());
+ for (size_t U = 0; U < debug_info.GetNumUnits(); ++U) {
+ DWARFUnit *unit = debug_info.GetUnitAtIndex(U);
if (unit && m_units_to_avoid.count(unit->GetOffset()) == 0)
units_to_index.push_back(unit);
}
@@ -44,10 +43,8 @@ void ManualDWARFIndex::Index() {
std::vector<IndexSet> sets(units_to_index.size());
- //----------------------------------------------------------------------
- // Keep memory down by clearing DIEs for any compile units if indexing
- // caused us to load the compile unit's DIEs.
- //----------------------------------------------------------------------
+ // Keep memory down by clearing DIEs for any units if indexing
+ // caused us to load the unit's DIEs.
std::vector<llvm::Optional<DWARFUnit::ScopedExtractDIEs>> clear_cu_dies(
units_to_index.size());
auto parser_fn = [&](size_t cu_idx) {
@@ -58,19 +55,17 @@ void ManualDWARFIndex::Index() {
clear_cu_dies[cu_idx] = units_to_index[cu_idx]->ExtractDIEsScoped();
};
- // Create a task runner that extracts dies for each DWARF compile unit in a
+ // Create a task runner that extracts dies for each DWARF unit in a
// separate thread
- //----------------------------------------------------------------------
- // First figure out which compile units didn't have their DIEs already
+ // First figure out which units didn't have their DIEs already
// parsed and remember this. If no DIEs were parsed prior to this index
// function call, we are going to want to clear the CU dies after we are
// done indexing to make sure we don't pull in all DWARF dies, but we need
- // to wait until all compile units have been indexed in case a DIE in one
- // compile unit refers to another and the indexes accesses those DIEs.
- //----------------------------------------------------------------------
+ // to wait until all units have been indexed in case a DIE in one
+ // unit refers to another and the indexes accesses those DIEs.
TaskMapOverInt(0, units_to_index.size(), extract_fn);
- // Now create a task runner that can index each DWARF compile unit in a
+ // Now create a task runner that can index each DWARF unit in a
// separate thread so we can index quickly.
TaskMapOverInt(0, units_to_index.size(), parser_fn);
@@ -93,30 +88,32 @@ void ManualDWARFIndex::Index() {
}
void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, IndexSet &set) {
+ assert(
+ !unit.GetSymbolFileDWARF().GetBaseCompileUnit() &&
+ "DWARFUnit associated with .dwo or .dwp should not be indexed directly");
+
Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS);
if (log) {
m_module.LogMessage(
- log, "ManualDWARFIndex::IndexUnit for compile unit at .debug_info[0x%8.8x]",
+ log, "ManualDWARFIndex::IndexUnit for unit at .debug_info[0x%8.8x]",
unit.GetOffset());
}
const LanguageType cu_language = unit.GetLanguageType();
- DWARFFormValue::FixedFormSizes fixed_form_sizes = unit.GetFixedFormSizes();
- IndexUnitImpl(unit, cu_language, fixed_form_sizes, unit.GetOffset(), set);
+ IndexUnitImpl(unit, cu_language, set);
- SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile();
- if (dwo_symbol_file && dwo_symbol_file->GetCompileUnit()) {
- IndexUnitImpl(*dwo_symbol_file->GetCompileUnit(), cu_language,
- fixed_form_sizes, unit.GetOffset(), set);
+ if (SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile()) {
+ DWARFDebugInfo &dwo_info = *dwo_symbol_file->DebugInfo();
+ for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i)
+ IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set);
}
}
-void ManualDWARFIndex::IndexUnitImpl(
- DWARFUnit &unit, const LanguageType cu_language,
- const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
- const dw_offset_t cu_offset, IndexSet &set) {
+void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
+ const LanguageType cu_language,
+ IndexSet &set) {
for (const DWARFDebugInfoEntry &die : unit.dies()) {
const dw_tag_t tag = die.Tag();
@@ -143,8 +140,8 @@ void ManualDWARFIndex::IndexUnitImpl(
}
DWARFAttributes attributes;
- const char *name = NULL;
- const char *mangled_cstr = NULL;
+ const char *name = nullptr;
+ const char *mangled_cstr = nullptr;
bool is_declaration = false;
// bool is_artificial = false;
bool has_address = false;
@@ -152,8 +149,7 @@ void ManualDWARFIndex::IndexUnitImpl(
bool is_global_or_static_variable = false;
DWARFFormValue specification_die_form;
- const size_t num_attributes =
- die.GetAttributes(&unit, fixed_form_sizes, attributes);
+ const size_t num_attributes = die.GetAttributes(&unit, attributes);
if (num_attributes > 0) {
for (uint32_t i = 0; i < num_attributes; ++i) {
dw_attr_t attr = attributes.AttributeAtIndex(i);
@@ -196,7 +192,7 @@ void ManualDWARFIndex::IndexUnitImpl(
has_location_or_const_value = true;
if (tag == DW_TAG_variable) {
const DWARFDebugInfoEntry *parent_die = die.GetParent();
- while (parent_die != NULL) {
+ while (parent_die != nullptr) {
switch (parent_die->Tag()) {
case DW_TAG_subprogram:
case DW_TAG_lexical_block:
@@ -215,19 +211,19 @@ void ManualDWARFIndex::IndexUnitImpl(
// if (block_data) {
// uint32_t block_length = form_value.Unsigned();
// if (block_length == 1 +
- // attributes.CompileUnitAtIndex(i)->GetAddressByteSize()) {
+ // attributes.UnitAtIndex(i)->GetAddressByteSize()) {
// if (block_data[0] == DW_OP_addr)
// add_die = true;
// }
// }
// }
- parent_die = NULL; // Terminate the while loop.
+ parent_die = nullptr; // Terminate the while loop.
break;
case DW_TAG_compile_unit:
case DW_TAG_partial_unit:
is_global_or_static_variable = true;
- parent_die = NULL; // Terminate the while loop.
+ parent_die = nullptr; // Terminate the while loop.
break;
default:
@@ -247,51 +243,48 @@ void ManualDWARFIndex::IndexUnitImpl(
}
}
+ DIERef ref = *DWARFDIE(&unit, &die).GetDIERef();
switch (tag) {
case DW_TAG_inlined_subroutine:
case DW_TAG_subprogram:
if (has_address) {
if (name) {
- ObjCLanguage::MethodName objc_method(name, true);
- if (objc_method.IsValid(true)) {
- ConstString objc_class_name_with_category(
- objc_method.GetClassNameWithCategory());
- ConstString objc_selector_name(objc_method.GetSelector());
- ConstString objc_fullname_no_category_name(
- objc_method.GetFullNameWithoutCategory(true));
- ConstString objc_class_name_no_category(objc_method.GetClassName());
- set.function_fullnames.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
- if (objc_class_name_with_category)
- set.objc_class_selectors.Insert(
- objc_class_name_with_category,
- DIERef(cu_offset, die.GetOffset()));
- if (objc_class_name_no_category &&
- objc_class_name_no_category != objc_class_name_with_category)
- set.objc_class_selectors.Insert(
- objc_class_name_no_category,
- DIERef(cu_offset, die.GetOffset()));
- if (objc_selector_name)
- set.function_selectors.Insert(objc_selector_name,
- DIERef(cu_offset, die.GetOffset()));
- if (objc_fullname_no_category_name)
- set.function_fullnames.Insert(objc_fullname_no_category_name,
- DIERef(cu_offset, die.GetOffset()));
+ bool is_objc_method = false;
+ if (cu_language == eLanguageTypeObjC ||
+ cu_language == eLanguageTypeObjC_plus_plus) {
+ ObjCLanguage::MethodName objc_method(name, true);
+ if (objc_method.IsValid(true)) {
+ is_objc_method = true;
+ ConstString class_name_with_category(
+ objc_method.GetClassNameWithCategory());
+ ConstString objc_selector_name(objc_method.GetSelector());
+ ConstString objc_fullname_no_category_name(
+ objc_method.GetFullNameWithoutCategory(true));
+ ConstString class_name_no_category(objc_method.GetClassName());
+ set.function_fullnames.Insert(ConstString(name), ref);
+ if (class_name_with_category)
+ set.objc_class_selectors.Insert(class_name_with_category, ref);
+ if (class_name_no_category &&
+ class_name_no_category != class_name_with_category)
+ set.objc_class_selectors.Insert(class_name_no_category, ref);
+ if (objc_selector_name)
+ set.function_selectors.Insert(objc_selector_name, ref);
+ if (objc_fullname_no_category_name)
+ set.function_fullnames.Insert(objc_fullname_no_category_name,
+ ref);
+ }
}
// If we have a mangled name, then the DW_AT_name attribute is
// usually the method name without the class or any parameters
bool is_method = DWARFDIE(&unit, &die).IsMethod();
if (is_method)
- set.function_methods.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
+ set.function_methods.Insert(ConstString(name), ref);
else
- set.function_basenames.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
+ set.function_basenames.Insert(ConstString(name), ref);
- if (!is_method && !mangled_cstr && !objc_method.IsValid(true))
- set.function_fullnames.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
+ if (!is_method && !mangled_cstr && !is_objc_method)
+ set.function_fullnames.Insert(ConstString(name), ref);
}
if (mangled_cstr) {
// Make sure our mangled name isn't the same string table entry as
@@ -301,8 +294,7 @@ void ManualDWARFIndex::IndexUnitImpl(
if (name && name != mangled_cstr &&
((mangled_cstr[0] == '_') ||
(::strcmp(name, mangled_cstr) != 0))) {
- set.function_fullnames.Insert(ConstString(mangled_cstr),
- DIERef(cu_offset, die.GetOffset()));
+ set.function_fullnames.Insert(ConstString(mangled_cstr), ref);
}
}
}
@@ -320,22 +312,19 @@ void ManualDWARFIndex::IndexUnitImpl(
case DW_TAG_union_type:
case DW_TAG_unspecified_type:
if (name && !is_declaration)
- set.types.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset()));
+ set.types.Insert(ConstString(name), ref);
if (mangled_cstr && !is_declaration)
- set.types.Insert(ConstString(mangled_cstr),
- DIERef(cu_offset, die.GetOffset()));
+ set.types.Insert(ConstString(mangled_cstr), ref);
break;
case DW_TAG_namespace:
if (name)
- set.namespaces.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
+ set.namespaces.Insert(ConstString(name), ref);
break;
case DW_TAG_variable:
if (name && has_location_or_const_value && is_global_or_static_variable) {
- set.globals.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
+ set.globals.Insert(ConstString(name), ref);
// Be sure to include variables by their mangled and demangled names if
// they have any since a variable can have a basename "i", a mangled
// named "_ZN12_GLOBAL__N_11iE" and a demangled mangled name
@@ -347,8 +336,7 @@ void ManualDWARFIndex::IndexUnitImpl(
// entries
if (mangled_cstr && name != mangled_cstr &&
((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) {
- set.globals.Insert(ConstString(mangled_cstr),
- DIERef(cu_offset, die.GetOffset()));
+ set.globals.Insert(ConstString(mangled_cstr), ref);
}
}
break;
@@ -370,10 +358,10 @@ void ManualDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
m_set.globals.Find(regex, offsets);
}
-void ManualDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
+void ManualDWARFIndex::GetGlobalVariables(const DWARFUnit &unit,
DIEArray &offsets) {
Index();
- m_set.globals.FindAllEntriesForCompileUnit(cu.GetOffset(), offsets);
+ m_set.globals.FindAllEntriesForUnit(unit, offsets);
}
void ManualDWARFIndex::GetObjCMethods(ConstString class_name,
@@ -405,7 +393,7 @@ void ManualDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
m_set.namespaces.Find(name, offsets);
}
-void ManualDWARFIndex::GetFunctions(ConstString name, DWARFDebugInfo &info,
+void ManualDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
uint32_t name_type_mask,
std::vector<DWARFDIE> &dies) {
@@ -417,7 +405,7 @@ void ManualDWARFIndex::GetFunctions(ConstString name, DWARFDebugInfo &info,
m_set.function_methods.Find(name, offsets);
m_set.function_fullnames.Find(name, offsets);
for (const DIERef &die_ref: offsets) {
- DWARFDIE die = info.GetDIE(die_ref);
+ DWARFDIE die = dwarf.GetDIE(die_ref);
if (!die)
continue;
if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die))
@@ -428,7 +416,7 @@ void ManualDWARFIndex::GetFunctions(ConstString name, DWARFDebugInfo &info,
DIEArray offsets;
m_set.function_basenames.Find(name, offsets);
for (const DIERef &die_ref: offsets) {
- DWARFDIE die = info.GetDIE(die_ref);
+ DWARFDIE die = dwarf.GetDIE(die_ref);
if (!die)
continue;
if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die))
@@ -441,7 +429,7 @@ void ManualDWARFIndex::GetFunctions(ConstString name, DWARFDebugInfo &info,
DIEArray offsets;
m_set.function_methods.Find(name, offsets);
for (const DIERef &die_ref: offsets) {
- if (DWARFDIE die = info.GetDIE(die_ref))
+ if (DWARFDIE die = dwarf.GetDIE(die_ref))
dies.push_back(die);
}
}
@@ -451,7 +439,7 @@ void ManualDWARFIndex::GetFunctions(ConstString name, DWARFDebugInfo &info,
DIEArray offsets;
m_set.function_selectors.Find(name, offsets);
for (const DIERef &die_ref: offsets) {
- if (DWARFDIE die = info.GetDIE(die_ref))
+ if (DWARFDIE die = dwarf.GetDIE(die_ref))
dies.push_back(die);
}
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
index 79ab1d95b380..dd03b103c936 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
@@ -1,9 +1,8 @@
-//===-- ManulaDWARFIndex.h -------------------------------------*- C++ -*-===//
+//===-- ManualDWARFIndex.h --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -14,6 +13,8 @@
#include "Plugins/SymbolFile/DWARF/NameToDIE.h"
#include "llvm/ADT/DenseSet.h"
+class DWARFDebugInfo;
+
namespace lldb_private {
class ManualDWARFIndex : public DWARFIndex {
public:
@@ -27,21 +28,20 @@ public:
void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
void GetGlobalVariables(const RegularExpression &regex,
DIEArray &offsets) override;
- void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;
+ void GetGlobalVariables(const DWARFUnit &unit, DIEArray &offsets) override;
void GetObjCMethods(ConstString class_name, DIEArray &offsets) override;
void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
DIEArray &offsets) override;
void GetTypes(ConstString name, DIEArray &offsets) override;
void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
void GetNamespaces(ConstString name, DIEArray &offsets) override;
- void GetFunctions(ConstString name, DWARFDebugInfo &info,
+ void GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
uint32_t name_type_mask,
std::vector<DWARFDIE> &dies) override;
void GetFunctions(const RegularExpression &regex, DIEArray &offsets) override;
- void ReportInvalidDIEOffset(dw_offset_t offset,
- llvm::StringRef name) override {}
+ void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {}
void Dump(Stream &s) override;
private:
@@ -58,10 +58,9 @@ private:
void Index();
void IndexUnit(DWARFUnit &unit, IndexSet &set);
- static void
- IndexUnitImpl(DWARFUnit &unit, const lldb::LanguageType cu_language,
- const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
- const dw_offset_t cu_offset, IndexSet &set);
+ static void IndexUnitImpl(DWARFUnit &unit,
+ const lldb::LanguageType cu_language,
+ IndexSet &set);
/// Non-null value means we haven't built the index yet.
DWARFDebugInfo *m_debug_info;
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
index c8d6bba16976..7d81afb1b226 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
@@ -1,23 +1,19 @@
//===-- NameToDIE.cpp -------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "NameToDIE.h"
+#include "DWARFUnit.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
-#include "DWARFDebugInfo.h"
-#include "DWARFDebugInfoEntry.h"
-#include "SymbolFileDWARF.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -26,11 +22,11 @@ void NameToDIE::Finalize() {
m_map.SizeToFit();
}
-void NameToDIE::Insert(const ConstString &name, const DIERef &die_ref) {
+void NameToDIE::Insert(ConstString name, const DIERef &die_ref) {
m_map.Append(name, die_ref);
}
-size_t NameToDIE::Find(const ConstString &name, DIEArray &info_array) const {
+size_t NameToDIE::Find(ConstString name, DIEArray &info_array) const {
return m_map.GetValues(name, info_array);
}
@@ -39,13 +35,16 @@ size_t NameToDIE::Find(const RegularExpression &regex,
return m_map.GetValues(regex, info_array);
}
-size_t NameToDIE::FindAllEntriesForCompileUnit(dw_offset_t cu_offset,
- DIEArray &info_array) const {
+size_t NameToDIE::FindAllEntriesForUnit(const DWARFUnit &unit,
+ DIEArray &info_array) const {
const size_t initial_size = info_array.size();
const uint32_t size = m_map.GetSize();
for (uint32_t i = 0; i < size; ++i) {
const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i);
- if (cu_offset == die_ref.cu_offset)
+ if (unit.GetSymbolFileDWARF().GetDwoNum() == die_ref.dwo_num() &&
+ unit.GetDebugSection() == die_ref.section() &&
+ unit.GetOffset() <= die_ref.die_offset() &&
+ die_ref.die_offset() < unit.GetNextUnitOffset())
info_array.push_back(die_ref);
}
return info_array.size() - initial_size;
@@ -54,10 +53,8 @@ size_t NameToDIE::FindAllEntriesForCompileUnit(dw_offset_t cu_offset,
void NameToDIE::Dump(Stream *s) {
const uint32_t size = m_map.GetSize();
for (uint32_t i = 0; i < size; ++i) {
- ConstString cstr = m_map.GetCStringAtIndex(i);
- const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i);
- s->Printf("%p: {0x%8.8x/0x%8.8x} \"%s\"\n", (const void *)cstr.GetCString(),
- die_ref.cu_offset, die_ref.die_offset, cstr.GetCString());
+ s->Format("{0} \"{1}\"\n", m_map.GetValueAtIndexUnchecked(i),
+ m_map.GetCStringAtIndexUnchecked(i));
}
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
index bba44fda3c04..b504f45e81b5 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
@@ -1,9 +1,8 @@
//===-- NameToDIE.h ---------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -17,7 +16,7 @@
#include "lldb/Core/dwarf.h"
#include "lldb/lldb-defines.h"
-class SymbolFileDWARF;
+class DWARFUnit;
class NameToDIE {
public:
@@ -27,20 +26,20 @@ public:
void Dump(lldb_private::Stream *s);
- void Insert(const lldb_private::ConstString &name, const DIERef &die_ref);
+ void Insert(lldb_private::ConstString name, const DIERef &die_ref);
void Append(const NameToDIE &other);
void Finalize();
- size_t Find(const lldb_private::ConstString &name,
+ size_t Find(lldb_private::ConstString name,
DIEArray &info_array) const;
size_t Find(const lldb_private::RegularExpression &regex,
DIEArray &info_array) const;
- size_t FindAllEntriesForCompileUnit(dw_offset_t cu_offset,
- DIEArray &info_array) const;
+ size_t FindAllEntriesForUnit(const DWARFUnit &unit,
+ DIEArray &info_array) const;
void
ForEach(std::function<bool(lldb_private::ConstString name,
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 2a0a89f0b25a..e2ddcfc5d64b 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1,9 +1,8 @@
//===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -30,7 +29,6 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
-#include "lldb/Host/Symbols.h"
#include "lldb/Interpreter/OptionValueFileSpecList.h"
#include "lldb/Interpreter/OptionValueProperties.h"
@@ -43,6 +41,7 @@
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/DebugMacros.h"
#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TypeMap.h"
@@ -50,11 +49,12 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Language.h"
+#include "lldb/Target/Target.h"
#include "AppleDWARFIndex.h"
#include "DWARFASTParser.h"
#include "DWARFASTParserClang.h"
-#include "DWARFDIECollection.h"
+#include "DWARFCompileUnit.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
@@ -63,6 +63,7 @@
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
#include "DWARFFormValue.h"
+#include "DWARFTypeUnit.h"
#include "DWARFUnit.h"
#include "DebugNamesDWARFIndex.h"
#include "LogChannelDWARF.h"
@@ -73,7 +74,9 @@
#include "llvm/Support/FileSystem.h"
+#include <algorithm>
#include <map>
+#include <memory>
#include <ctype.h>
#include <string.h>
@@ -131,12 +134,12 @@ public:
}
PluginProperties() {
- m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
m_collection_sp->Initialize(g_properties);
}
- FileSpecList &GetSymLinkPaths() {
- OptionValueFileSpecList *option_value =
+ FileSpecList GetSymLinkPaths() {
+ const OptionValueFileSpecList *option_value =
m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(
nullptr, true, ePropertySymLinkPaths);
assert(option_value);
@@ -158,68 +161,8 @@ static const SymbolFileDWARFPropertiesSP &GetGlobalPluginProperties() {
} // anonymous namespace end
-static const char *removeHostnameFromPathname(const char *path_from_dwarf) {
- if (!path_from_dwarf || !path_from_dwarf[0]) {
- return path_from_dwarf;
- }
-
- const char *colon_pos = strchr(path_from_dwarf, ':');
- if (nullptr == colon_pos) {
- return path_from_dwarf;
- }
-
- const char *slash_pos = strchr(path_from_dwarf, '/');
- if (slash_pos && (slash_pos < colon_pos)) {
- return path_from_dwarf;
- }
-
- // check whether we have a windows path, and so the first character is a
- // drive-letter not a hostname.
- if (colon_pos == path_from_dwarf + 1 && isalpha(*path_from_dwarf) &&
- strlen(path_from_dwarf) > 2 && '\\' == path_from_dwarf[2]) {
- return path_from_dwarf;
- }
-
- return colon_pos + 1;
-}
-
-static FileSpec resolveCompDir(const char *path_from_dwarf) {
- if (!path_from_dwarf)
- return FileSpec();
-
- // DWARF2/3 suggests the form hostname:pathname for compilation directory.
- // Remove the host part if present.
- const char *local_path = removeHostnameFromPathname(path_from_dwarf);
- if (!local_path)
- return FileSpec();
-
- bool is_symlink = false;
- // Always normalize our compile unit directory to get rid of redundant
- // slashes and other path anomalies before we use it for path prepending
- FileSpec local_spec(local_path);
- const auto &file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
- for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
- is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i),
- local_spec, true);
-
- if (!is_symlink)
- return local_spec;
-
- namespace fs = llvm::sys::fs;
- if (fs::get_file_type(local_spec.GetPath(), false) !=
- fs::file_type::symlink_file)
- return local_spec;
-
- FileSpec resolved_symlink;
- const auto error = FileSystem::Instance().Readlink(local_spec, resolved_symlink);
- if (error.Success())
- return resolved_symlink;
-
- return local_spec;
-}
-
-DWARFUnit *SymbolFileDWARF::GetBaseCompileUnit() {
- return nullptr;
+FileSpecList SymbolFileDWARF::GetSymlinkPaths() {
+ return GetGlobalPluginProperties()->GetSymLinkPaths();
}
void SymbolFileDWARF::Initialize() {
@@ -255,7 +198,8 @@ const char *SymbolFileDWARF::GetPluginDescriptionStatic() {
}
SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileDWARF(obj_file);
+ return new SymbolFileDWARF(obj_file,
+ /*dwo_section_list*/ nullptr);
}
TypeList *SymbolFileDWARF::GetTypeList() {
@@ -346,23 +290,23 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
ASSERT_MODULE_LOCK(this);
TypeSet type_set;
- CompileUnit *comp_unit = NULL;
- DWARFUnit *dwarf_cu = NULL;
+ CompileUnit *comp_unit = nullptr;
+ DWARFUnit *dwarf_cu = nullptr;
if (sc_scope)
comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
if (comp_unit) {
dwarf_cu = GetDWARFCompileUnit(comp_unit);
- if (dwarf_cu == 0)
+ if (dwarf_cu == nullptr)
return 0;
GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(),
- dwarf_cu->GetNextCompileUnitOffset(), type_mask, type_set);
+ dwarf_cu->GetNextUnitOffset(), type_mask, type_set);
} else {
DWARFDebugInfo *info = DebugInfo();
if (info) {
- const size_t num_cus = info->GetNumCompileUnits();
+ const size_t num_cus = info->GetNumUnits();
for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) {
- dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
+ dwarf_cu = info->GetUnitAtIndex(cu_idx);
if (dwarf_cu) {
GetTypes(dwarf_cu->DIE(), 0, UINT32_MAX, type_mask, type_set);
}
@@ -383,10 +327,8 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
return num_types_added;
}
-//----------------------------------------------------------------------
// Gets the first parent that is a lexical block, function or inlined
// subroutine, or compile unit.
-//----------------------------------------------------------------------
DWARFDIE
SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {
DWARFDIE die;
@@ -405,23 +347,21 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {
return DWARFDIE();
}
-SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile)
- : SymbolFile(objfile), UserID(uint64_t(DW_INVALID_OFFSET)
- << 32), // Used by SymbolFileDWARFDebugMap to
- // when this class parses .o files to
- // contain the .o file index/ID
- m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(),
- m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(),
- m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(),
- m_data_debug_ranges(), m_data_debug_rnglists(), m_data_debug_str(),
- m_data_apple_names(), m_data_apple_types(), m_data_apple_namespaces(),
- m_abbr(), m_info(), m_line(), m_fetched_external_modules(false),
- m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(),
+SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile,
+ SectionList *dwo_section_list)
+ : SymbolFile(objfile),
+ UserID(0x7fffffff00000000), // Used by SymbolFileDWARFDebugMap to
+ // when this class parses .o files to
+ // contain the .o file index/ID
+ m_debug_map_module_wp(), m_debug_map_symfile(nullptr),
+ m_context(objfile->GetModule()->GetSectionList(), dwo_section_list),
+ m_data_debug_loc(), m_abbr(), m_info(), m_fetched_external_modules(false),
+ m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate),
m_unique_ast_type_map() {}
SymbolFileDWARF::~SymbolFileDWARF() {}
-static const ConstString &GetDWARFMachOSegmentName() {
+static ConstString GetDWARFMachOSegmentName() {
static ConstString g_dwarf_section_name("__DWARF");
return g_dwarf_section_name;
}
@@ -449,15 +389,6 @@ TypeSystem *SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
void SymbolFileDWARF::InitializeObject() {
Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
- ModuleSP module_sp(m_obj_file->GetModule());
- if (module_sp) {
- const SectionList *section_list = module_sp->GetSectionList();
- Section *section =
- section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();
-
- if (section)
- m_obj_file->ReadSectionData(section, m_dwarf_data);
- }
if (!GetGlobalPluginProperties()->IgnoreFileIndexes()) {
DWARFDataExtractor apple_names, apple_namespaces, apple_types, apple_objc;
@@ -468,7 +399,7 @@ void SymbolFileDWARF::InitializeObject() {
m_index = AppleDWARFIndex::Create(
*GetObjectFile()->GetModule(), apple_names, apple_namespaces,
- apple_types, apple_objc, get_debug_str_data());
+ apple_types, apple_objc, m_context.getOrLoadStrData());
if (m_index)
return;
@@ -477,9 +408,9 @@ void SymbolFileDWARF::InitializeObject() {
LoadSectionData(eSectionTypeDWARFDebugNames, debug_names);
if (debug_names.GetByteSize() > 0) {
llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =
- DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(),
- debug_names, get_debug_str_data(),
- DebugInfo());
+ DebugNamesDWARFIndex::Create(
+ *GetObjectFile()->GetModule(), debug_names,
+ m_context.getOrLoadStrData(), DebugInfo());
if (index_or) {
m_index = std::move(*index_or);
return;
@@ -499,25 +430,11 @@ bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
uint32_t SymbolFileDWARF::CalculateAbilities() {
uint32_t abilities = 0;
- if (m_obj_file != NULL) {
- const Section *section = NULL;
+ if (m_obj_file != nullptr) {
+ const Section *section = nullptr;
const SectionList *section_list = m_obj_file->GetSectionList();
- if (section_list == NULL)
- return 0;
-
- // On non Apple platforms we might have .debug_types debug info that is
- // created by using "-fdebug-types-section". LLDB currently will try to
- // load this debug info, but it causes crashes during debugging when types
- // are missing since it doesn't know how to parse the info in the
- // .debug_types type units. This causes all complex debug info types to be
- // unresolved. Because this causes LLDB to crash and since it really
- // doesn't provide a solid debuggiung experience, we should disable trying
- // to debug this kind of DWARF until support gets added or deprecated.
- if (section_list->FindSectionByName(ConstString(".debug_types"))) {
- m_obj_file->GetModule()->ReportWarning(
- "lldb doesn’t support .debug_types debug info");
+ if (section_list == nullptr)
return 0;
- }
uint64_t debug_abbrev_file_size = 0;
uint64_t debug_info_file_size = 0;
@@ -530,7 +447,7 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
section =
section_list->FindSectionByType(eSectionTypeDWARFDebugInfo, true).get();
- if (section != NULL) {
+ if (section != nullptr) {
debug_info_file_size = section->GetFileSize();
section =
@@ -604,53 +521,15 @@ void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,
DWARFDataExtractor &data) {
ModuleSP module_sp(m_obj_file->GetModule());
const SectionList *section_list = module_sp->GetSectionList();
- if (section_list) {
- SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
- if (section_sp) {
- // See if we memory mapped the DWARF segment?
- if (m_dwarf_data.GetByteSize()) {
- data.SetData(m_dwarf_data, section_sp->GetOffset(),
- section_sp->GetFileSize());
- } else {
- if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0)
- data.Clear();
- }
- }
- }
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_abbrev_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugAbbrev,
- m_data_debug_abbrev);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_addr_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugAddr, m_data_debug_addr);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_aranges_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugAranges,
- m_data_debug_aranges);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_frame_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugFrame, m_data_debug_frame);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugInfo, m_data_debug_info);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line);
-}
+ if (!section_list)
+ return;
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_str_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugLineStr, m_data_debug_line_str);
-}
+ SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
+ if (!section_sp)
+ return;
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro);
+ data.Clear();
+ m_obj_file->ReadSectionData(section_sp.get(), data);
}
const DWARFDataExtractor &SymbolFileDWARF::DebugLocData() {
@@ -669,60 +548,24 @@ const DWARFDataExtractor &SymbolFileDWARF::get_debug_loclists_data() {
m_data_debug_loclists);
}
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_ranges_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugRanges,
- m_data_debug_ranges);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_rnglists_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugRngLists,
- m_data_debug_rnglists);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugStr, m_data_debug_str);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_offsets_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugStrOffsets,
- m_data_debug_str_offsets);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_types_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugTypes, m_data_debug_types);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_apple_names_data() {
- return GetCachedSectionData(eSectionTypeDWARFAppleNames, m_data_apple_names);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_apple_types_data() {
- return GetCachedSectionData(eSectionTypeDWARFAppleTypes, m_data_apple_types);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_apple_namespaces_data() {
- return GetCachedSectionData(eSectionTypeDWARFAppleNamespaces,
- m_data_apple_namespaces);
-}
-
-const DWARFDataExtractor &SymbolFileDWARF::get_apple_objc_data() {
- return GetCachedSectionData(eSectionTypeDWARFAppleObjC, m_data_apple_objc);
-}
+DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
+ if (m_abbr)
+ return m_abbr.get();
-const DWARFDataExtractor &SymbolFileDWARF::get_gnu_debugaltlink() {
- return GetCachedSectionData(eSectionTypeDWARFGNUDebugAltLink,
- m_data_gnu_debugaltlink);
-}
+ const DWARFDataExtractor &debug_abbrev_data = m_context.getOrLoadAbbrevData();
+ if (debug_abbrev_data.GetByteSize() == 0)
+ return nullptr;
-DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
- if (m_abbr.get() == NULL) {
- const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
- if (debug_abbrev_data.GetByteSize() > 0) {
- m_abbr.reset(new DWARFDebugAbbrev());
- if (m_abbr.get())
- m_abbr->Parse(debug_abbrev_data);
- }
+ auto abbr = llvm::make_unique<DWARFDebugAbbrev>();
+ llvm::Error error = abbr->parse(debug_abbrev_data);
+ if (error) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ LLDB_LOG_ERROR(log, std::move(error),
+ "Unable to read .debug_abbrev section: {0}");
+ return nullptr;
}
+
+ m_abbr = std::move(abbr);
return m_abbr.get();
}
@@ -731,16 +574,12 @@ const DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() const {
}
DWARFDebugInfo *SymbolFileDWARF::DebugInfo() {
- if (m_info.get() == NULL) {
+ if (m_info == nullptr) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
static_cast<void *>(this));
- if (get_debug_info_data().GetByteSize() > 0) {
- m_info.reset(new DWARFDebugInfo());
- if (m_info.get()) {
- m_info->SetDwarfData(this);
- }
- }
+ if (m_context.getOrLoadDebugInfoData().GetByteSize() > 0)
+ m_info = llvm::make_unique<DWARFDebugInfo>(*this, m_context);
}
return m_info.get();
}
@@ -756,109 +595,90 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
DWARFDebugInfo *info = DebugInfo();
if (info) {
- // Just a normal DWARF file whose user ID for the compile unit is the DWARF
- // offset itself
-
- DWARFUnit *dwarf_cu =
- info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
- if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
+ // The compile unit ID is the index of the DWARF unit.
+ DWARFUnit *dwarf_cu = info->GetUnitAtIndex(comp_unit->GetID());
+ if (dwarf_cu && dwarf_cu->GetUserData() == nullptr)
dwarf_cu->SetUserData(comp_unit);
return dwarf_cu;
}
- return NULL;
+ return nullptr;
}
-DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() {
- if (m_ranges.get() == NULL) {
+DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRanges() {
+ if (!m_ranges) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
static_cast<void *>(this));
- if (get_debug_ranges_data().GetByteSize() > 0)
+ if (m_context.getOrLoadRangesData().GetByteSize() > 0)
m_ranges.reset(new DWARFDebugRanges());
- else if (get_debug_rnglists_data().GetByteSize() > 0)
- m_ranges.reset(new DWARFDebugRngLists());
- if (m_ranges.get())
- m_ranges->Extract(this);
+ if (m_ranges)
+ m_ranges->Extract(m_context);
}
return m_ranges.get();
}
-const DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() const {
- return m_ranges.get();
+DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRngLists() {
+ if (!m_rnglists) {
+ static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+ Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
+ static_cast<void *>(this));
+
+ if (m_context.getOrLoadRngListsData().GetByteSize() > 0)
+ m_rnglists.reset(new DWARFDebugRngLists());
+
+ if (m_rnglists)
+ m_rnglists->Extract(m_context);
+ }
+ return m_rnglists.get();
}
-lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu,
- uint32_t cu_idx) {
+lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
CompUnitSP cu_sp;
- if (dwarf_cu) {
- CompileUnit *comp_unit = (CompileUnit *)dwarf_cu->GetUserData();
- if (comp_unit) {
- // We already parsed this compile unit, had out a shared pointer to it
- cu_sp = comp_unit->shared_from_this();
+ CompileUnit *comp_unit = (CompileUnit *)dwarf_cu.GetUserData();
+ if (comp_unit) {
+ // We already parsed this compile unit, had out a shared pointer to it
+ cu_sp = comp_unit->shared_from_this();
+ } else {
+ if (&dwarf_cu.GetSymbolFileDWARF() != this) {
+ return dwarf_cu.GetSymbolFileDWARF().ParseCompileUnit(dwarf_cu);
+ } else if (dwarf_cu.GetOffset() == 0 && GetDebugMapSymfile()) {
+ // Let the debug map create the compile unit
+ cu_sp = m_debug_map_symfile->GetCompileUnit(this);
+ dwarf_cu.SetUserData(cu_sp.get());
} else {
- if (dwarf_cu->GetSymbolFileDWARF() != this) {
- return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu,
- cu_idx);
- } else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile()) {
- // Let the debug map create the compile unit
- cu_sp = m_debug_map_symfile->GetCompileUnit(this);
- dwarf_cu->SetUserData(cu_sp.get());
- } else {
- ModuleSP module_sp(m_obj_file->GetModule());
- if (module_sp) {
- const DWARFDIE cu_die = dwarf_cu->DIE();
- if (cu_die) {
- FileSpec cu_file_spec(cu_die.GetName());
- if (cu_file_spec) {
- // If we have a full path to the compile unit, we don't need to
- // resolve the file. This can be expensive e.g. when the source
- // files are
- // NFS mounted.
- if (cu_file_spec.IsRelative()) {
- const char *cu_comp_dir{
- cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)};
- cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
- }
-
- std::string remapped_file;
- if (module_sp->RemapSourceFile(cu_file_spec.GetPath(),
- remapped_file))
- cu_file_spec.SetFile(remapped_file, FileSpec::Style::native);
- }
+ ModuleSP module_sp(m_obj_file->GetModule());
+ if (module_sp) {
+ const DWARFDIE cu_die = dwarf_cu.DIE();
+ if (cu_die) {
+ FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu.GetPathStyle());
+ if (cu_file_spec) {
+ // If we have a full path to the compile unit, we don't need to
+ // resolve the file. This can be expensive e.g. when the source
+ // files are NFS mounted.
+ cu_file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory());
+
+ std::string remapped_file;
+ if (module_sp->RemapSourceFile(cu_file_spec.GetPath(),
+ remapped_file))
+ cu_file_spec.SetFile(remapped_file, FileSpec::Style::native);
+ }
- LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF(
- cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
-
- bool is_optimized = dwarf_cu->GetIsOptimized();
- cu_sp.reset(new CompileUnit(
- module_sp, dwarf_cu, cu_file_spec, dwarf_cu->GetID(),
- cu_language, is_optimized ? eLazyBoolYes : eLazyBoolNo));
- if (cu_sp) {
- // If we just created a compile unit with an invalid file spec,
- // try and get the first entry in the supports files from the
- // line table as that should be the compile unit.
- if (!cu_file_spec) {
- cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
- if (cu_file_spec) {
- (FileSpec &)(*cu_sp) = cu_file_spec;
- // Also fix the invalid file spec which was copied from the
- // compile unit.
- cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
- }
- }
+ LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF(
+ cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
- dwarf_cu->SetUserData(cu_sp.get());
+ bool is_optimized = dwarf_cu.GetIsOptimized();
+ BuildCuTranslationTable();
+ cu_sp = std::make_shared<CompileUnit>(
+ module_sp, &dwarf_cu, cu_file_spec,
+ *GetDWARFUnitIndex(dwarf_cu.GetID()), cu_language,
+ is_optimized ? eLazyBoolYes : eLazyBoolNo);
- // Figure out the compile unit index if we weren't given one
- if (cu_idx == UINT32_MAX)
- DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
+ dwarf_cu.SetUserData(cu_sp.get());
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- cu_idx, cu_sp);
- }
- }
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
+ dwarf_cu.GetID(), cu_sp);
}
}
}
@@ -866,23 +686,56 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu,
return cu_sp;
}
+void SymbolFileDWARF::BuildCuTranslationTable() {
+ if (!m_lldb_cu_to_dwarf_unit.empty())
+ return;
+
+ DWARFDebugInfo *info = DebugInfo();
+ if (!info)
+ return;
+
+ if (!info->ContainsTypeUnits()) {
+ // We can use a 1-to-1 mapping. No need to build a translation table.
+ return;
+ }
+ for (uint32_t i = 0, num = info->GetNumUnits(); i < num; ++i) {
+ if (auto *cu = llvm::dyn_cast<DWARFCompileUnit>(info->GetUnitAtIndex(i))) {
+ cu->SetID(m_lldb_cu_to_dwarf_unit.size());
+ m_lldb_cu_to_dwarf_unit.push_back(i);
+ }
+ }
+}
+
+llvm::Optional<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) {
+ BuildCuTranslationTable();
+ if (m_lldb_cu_to_dwarf_unit.empty())
+ return cu_idx;
+ if (cu_idx >= m_lldb_cu_to_dwarf_unit.size())
+ return llvm::None;
+ return m_lldb_cu_to_dwarf_unit[cu_idx];
+}
+
uint32_t SymbolFileDWARF::GetNumCompileUnits() {
DWARFDebugInfo *info = DebugInfo();
- if (info)
- return info->GetNumCompileUnits();
- return 0;
+ if (!info)
+ return 0;
+ BuildCuTranslationTable();
+ return m_lldb_cu_to_dwarf_unit.empty() ? info->GetNumUnits()
+ : m_lldb_cu_to_dwarf_unit.size();
}
CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
ASSERT_MODULE_LOCK(this);
- CompUnitSP cu_sp;
DWARFDebugInfo *info = DebugInfo();
- if (info) {
- DWARFUnit *dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu)
- cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
+ if (!info)
+ return {};
+
+ if (llvm::Optional<uint32_t> dwarf_idx = GetDWARFUnitIndex(cu_idx)) {
+ if (auto *dwarf_cu = llvm::cast_or_null<DWARFCompileUnit>(
+ info->GetUnitAtIndex(*dwarf_idx)))
+ return ParseCompileUnit(*dwarf_cu);
}
- return cu_sp;
+ return {};
}
Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
@@ -920,50 +773,74 @@ lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {
size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
ASSERT_MODULE_LOCK(this);
- size_t functions_added = 0;
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
- if (dwarf_cu) {
- DWARFDIECollection function_dies;
- const size_t num_functions =
- dwarf_cu->AppendDIEsWithTag(DW_TAG_subprogram, function_dies);
- size_t func_idx;
- for (func_idx = 0; func_idx < num_functions; ++func_idx) {
- DWARFDIE die = function_dies.GetDIEAtIndex(func_idx);
- if (comp_unit.FindFunctionByUID(die.GetID()).get() == NULL) {
- if (ParseFunction(comp_unit, die))
- ++functions_added;
- }
- }
- // FixupTypes();
+ if (!dwarf_cu)
+ return 0;
+
+ size_t functions_added = 0;
+ std::vector<DWARFDIE> function_dies;
+ dwarf_cu->AppendDIEsWithTag(DW_TAG_subprogram, function_dies);
+ for (const DWARFDIE &die : function_dies) {
+ if (comp_unit.FindFunctionByUID(die.GetID()))
+ continue;
+ if (ParseFunction(comp_unit, die))
+ ++functions_added;
}
+ // FixupTypes();
return functions_added;
}
bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
ASSERT_MODULE_LOCK(this);
- DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
- if (dwarf_cu) {
- const DWARFBaseDIE cu_die = dwarf_cu->GetUnitDIEOnly();
-
- if (cu_die) {
- FileSpec cu_comp_dir = resolveCompDir(
- cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
- const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(
- DW_AT_stmt_list, DW_INVALID_OFFSET);
- if (stmt_list != DW_INVALID_OFFSET) {
- // All file indexes in DWARF are one based and a file of index zero is
- // supposed to be the compile unit itself.
- support_files.Append(comp_unit);
- return DWARFDebugLine::ParseSupportFiles(
- comp_unit.GetModule(), get_debug_line_data(), cu_comp_dir,
- stmt_list, support_files, dwarf_cu);
- }
+ if (DWARFUnit *unit = GetDWARFCompileUnit(&comp_unit)) {
+ const dw_offset_t stmt_list = unit->GetLineTableOffset();
+ if (stmt_list != DW_INVALID_OFFSET) {
+ // All file indexes in DWARF are one based and a file of index zero is
+ // supposed to be the compile unit itself.
+ support_files.Append(comp_unit);
+ return DWARFDebugLine::ParseSupportFiles(comp_unit.GetModule(),
+ m_context.getOrLoadLineData(),
+ stmt_list, support_files, unit);
}
}
return false;
}
+FileSpec SymbolFileDWARF::GetFile(DWARFUnit &unit, size_t file_idx) {
+ if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit)) {
+ if (CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(*dwarf_cu))
+ return lldb_cu->GetSupportFiles().GetFileSpecAtIndex(file_idx);
+ return FileSpec();
+ }
+
+ auto &tu = llvm::cast<DWARFTypeUnit>(unit);
+ return GetTypeUnitSupportFiles(tu).GetFileSpecAtIndex(file_idx);
+}
+
+const FileSpecList &
+SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) {
+ static FileSpecList empty_list;
+
+ dw_offset_t offset = tu.GetLineTableOffset();
+ if (offset == DW_INVALID_OFFSET ||
+ offset == llvm::DenseMapInfo<dw_offset_t>::getEmptyKey() ||
+ offset == llvm::DenseMapInfo<dw_offset_t>::getTombstoneKey())
+ return empty_list;
+
+ // Many type units can share a line table, so parse the support file list
+ // once, and cache it based on the offset field.
+ auto iter_bool = m_type_unit_support_files.try_emplace(offset);
+ FileSpecList &list = iter_bool.first->second;
+ if (iter_bool.second) {
+ list.Append(FileSpec());
+ DWARFDebugLine::ParseSupportFiles(GetObjectFile()->GetModule(),
+ m_context.getOrLoadLineData(), offset,
+ list, &tu);
+ }
+ return list;
+}
+
bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {
ASSERT_MODULE_LOCK(this);
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
@@ -974,54 +851,63 @@ bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {
bool SymbolFileDWARF::ParseImportedModules(
const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) {
+ std::vector<SourceModule> &imported_modules) {
ASSERT_MODULE_LOCK(this);
assert(sc.comp_unit);
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu) {
- if (ClangModulesDeclVendor::LanguageSupportsClangModules(
- sc.comp_unit->GetLanguage())) {
- UpdateExternalModuleListIfNeeded();
+ if (!dwarf_cu)
+ return false;
+ if (!ClangModulesDeclVendor::LanguageSupportsClangModules(
+ sc.comp_unit->GetLanguage()))
+ return false;
+ UpdateExternalModuleListIfNeeded();
- if (sc.comp_unit) {
- const DWARFDIE die = dwarf_cu->DIE();
+ const DWARFDIE die = dwarf_cu->DIE();
+ if (!die)
+ return false;
- if (die) {
- for (DWARFDIE child_die = die.GetFirstChild(); child_die;
- child_die = child_die.GetSibling()) {
- if (child_die.Tag() == DW_TAG_imported_declaration) {
- if (DWARFDIE module_die =
- child_die.GetReferencedDIE(DW_AT_import)) {
- if (module_die.Tag() == DW_TAG_module) {
- if (const char *name = module_die.GetAttributeValueAsString(
- DW_AT_name, nullptr)) {
- ConstString const_name(name);
- imported_modules.push_back(const_name);
- }
- }
- }
- }
- }
- }
- } else {
- for (const auto &pair : m_external_type_modules) {
- imported_modules.push_back(pair.first);
- }
+ for (DWARFDIE child_die = die.GetFirstChild(); child_die;
+ child_die = child_die.GetSibling()) {
+ if (child_die.Tag() != DW_TAG_imported_declaration)
+ continue;
+
+ DWARFDIE module_die = child_die.GetReferencedDIE(DW_AT_import);
+ if (module_die.Tag() != DW_TAG_module)
+ continue;
+
+ if (const char *name =
+ module_die.GetAttributeValueAsString(DW_AT_name, nullptr)) {
+ SourceModule module;
+ module.path.push_back(ConstString(name));
+
+ DWARFDIE parent_die = module_die;
+ while ((parent_die = parent_die.GetParent())) {
+ if (parent_die.Tag() != DW_TAG_module)
+ break;
+ if (const char *name =
+ parent_die.GetAttributeValueAsString(DW_AT_name, nullptr))
+ module.path.push_back(ConstString(name));
}
+ std::reverse(module.path.begin(), module.path.end());
+ if (const char *include_path = module_die.GetAttributeValueAsString(
+ DW_AT_LLVM_include_path, nullptr))
+ module.search_path = ConstString(include_path);
+ if (const char *sysroot = module_die.GetAttributeValueAsString(
+ DW_AT_LLVM_isysroot, nullptr))
+ module.sysroot = ConstString(sysroot);
+ imported_modules.push_back(module);
}
}
- return false;
+ return true;
}
struct ParseDWARFLineTableCallbackInfo {
LineTable *line_table;
- std::unique_ptr<LineSequence> sequence_ap;
+ std::unique_ptr<LineSequence> sequence_up;
lldb::addr_t addr_mask;
};
-//----------------------------------------------------------------------
// ParseStatementTableCallback
-//----------------------------------------------------------------------
static void ParseDWARFLineTableCallback(dw_offset_t offset,
const DWARFDebugLine::State &state,
void *userData) {
@@ -1035,26 +921,26 @@ static void ParseDWARFLineTableCallback(dw_offset_t offset,
LineTable *line_table = info->line_table;
// If this is our first time here, we need to create a sequence container.
- if (!info->sequence_ap.get()) {
- info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
- assert(info->sequence_ap.get());
+ if (!info->sequence_up) {
+ info->sequence_up.reset(line_table->CreateLineSequenceContainer());
+ assert(info->sequence_up.get());
}
line_table->AppendLineEntryToSequence(
- info->sequence_ap.get(), state.address & info->addr_mask, state.line,
+ info->sequence_up.get(), state.address & info->addr_mask, state.line,
state.column, state.file, 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.
- line_table->InsertSequence(info->sequence_ap.get());
+ line_table->InsertSequence(info->sequence_up.get());
// Then, empty it to prepare for the next sequence.
- info->sequence_ap->Clear();
+ info->sequence_up->Clear();
}
}
}
bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
ASSERT_MODULE_LOCK(this);
- if (comp_unit.GetLineTable() != NULL)
+ if (comp_unit.GetLineTable() != nullptr)
return true;
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
@@ -1065,10 +951,10 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list,
DW_INVALID_OFFSET);
if (cu_line_offset != DW_INVALID_OFFSET) {
- std::unique_ptr<LineTable> line_table_ap(new LineTable(&comp_unit));
- if (line_table_ap.get()) {
+ std::unique_ptr<LineTable> line_table_up(new LineTable(&comp_unit));
+ if (line_table_up) {
ParseDWARFLineTableCallbackInfo info;
- info.line_table = line_table_ap.get();
+ info.line_table = line_table_up.get();
/*
* MIPS:
@@ -1091,9 +977,9 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
}
lldb::offset_t offset = cu_line_offset;
- DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset,
- ParseDWARFLineTableCallback,
- &info, dwarf_cu);
+ DWARFDebugLine::ParseStatementTable(
+ m_context.getOrLoadLineData(), &offset,
+ ParseDWARFLineTableCallback, &info, dwarf_cu);
SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
if (debug_map_symfile) {
// We have an object file that has a line table with addresses that
@@ -1101,9 +987,9 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
// addresses that are relative to the .o file into addresses for
// the main executable.
comp_unit.SetLineTable(
- debug_map_symfile->LinkOSOLineTable(this, line_table_ap.get()));
+ debug_map_symfile->LinkOSOLineTable(this, line_table_up.get()));
} else {
- comp_unit.SetLineTable(line_table_ap.release());
+ comp_unit.SetLineTable(line_table_up.release());
return true;
}
}
@@ -1119,7 +1005,7 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) {
if (iter != m_debug_macros_map.end())
return iter->second;
- const DWARFDataExtractor &debug_macro_data = get_debug_macro_data();
+ const DWARFDataExtractor &debug_macro_data = m_context.getOrLoadMacroData();
if (debug_macro_data.GetByteSize() == 0)
return DebugMacrosSP();
@@ -1128,9 +1014,9 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) {
const DWARFDebugMacroHeader &header =
DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset);
- DWARFDebugMacroEntry::ReadMacroEntries(debug_macro_data, get_debug_str_data(),
- header.OffsetIs64Bit(), offset, this,
- debug_macros_sp);
+ DWARFDebugMacroEntry::ReadMacroEntries(
+ debug_macro_data, m_context.getOrLoadStrData(), header.OffsetIs64Bit(),
+ offset, this, debug_macros_sp);
return debug_macros_sp;
}
@@ -1171,7 +1057,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(
case DW_TAG_inlined_subroutine:
case DW_TAG_subprogram:
case DW_TAG_lexical_block: {
- Block *block = NULL;
+ Block *block = nullptr;
if (tag == DW_TAG_subprogram) {
// Skip any DW_TAG_subprogram DIEs that are inside of a normal or
// inlined functions. These will be parsed on their own as separate
@@ -1187,8 +1073,8 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(
block = block_sp.get();
}
DWARFRangeList ranges;
- const char *name = NULL;
- const char *mangled_name = NULL;
+ const char *name = nullptr;
+ const char *mangled_name = nullptr;
int decl_file = 0;
int decl_line = 0;
@@ -1236,21 +1122,21 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(
block->FinalizeRanges();
if (tag != DW_TAG_subprogram &&
- (name != NULL || mangled_name != NULL)) {
- std::unique_ptr<Declaration> decl_ap;
+ (name != nullptr || mangled_name != nullptr)) {
+ std::unique_ptr<Declaration> decl_up;
if (decl_file != 0 || decl_line != 0 || decl_column != 0)
- decl_ap.reset(new Declaration(
+ decl_up.reset(new Declaration(
comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file),
decl_line, decl_column));
- std::unique_ptr<Declaration> call_ap;
+ std::unique_ptr<Declaration> call_up;
if (call_file != 0 || call_line != 0 || call_column != 0)
- call_ap.reset(new Declaration(
+ call_up.reset(new Declaration(
comp_unit.GetSupportFiles().GetFileSpecAtIndex(call_file),
call_line, call_column));
- block->SetInlinedFunctionInfo(name, mangled_name, decl_ap.get(),
- call_ap.get());
+ block->SetInlinedFunctionInfo(name, mangled_name, decl_up.get(),
+ call_up.get());
}
++blocks_added;
@@ -1313,7 +1199,17 @@ void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
ast_parser->GetDeclForUIDFromDWARF(decl);
}
-SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) {
+user_id_t SymbolFileDWARF::GetUID(DIERef ref) {
+ if (GetDebugMapSymfile())
+ return GetID() | ref.die_offset();
+
+ return user_id_t(GetDwoNum().getValueOr(0x7fffffff)) << 32 |
+ ref.die_offset() |
+ (lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes) << 63);
+}
+
+llvm::Optional<SymbolFileDWARF::DecodedUID>
+SymbolFileDWARF::DecodeUID(lldb::user_id_t uid) {
// This method can be called without going through the symbol vendor so we
// need to lock the module.
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
@@ -1324,28 +1220,37 @@ SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) {
// references to other DWARF objects and we must be ready to receive a
// "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
// instance.
- SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile();
- if (debug_map)
- return debug_map->GetSymbolFileByOSOIndex(
+ if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) {
+ SymbolFileDWARF *dwarf = debug_map->GetSymbolFileByOSOIndex(
debug_map->GetOSOIndexFromUserID(uid));
- return this;
+ return DecodedUID{
+ *dwarf, {llvm::None, DIERef::Section::DebugInfo, dw_offset_t(uid)}};
+ }
+ dw_offset_t die_offset = uid;
+ if (die_offset == DW_INVALID_OFFSET)
+ return llvm::None;
+
+ DIERef::Section section =
+ uid >> 63 ? DIERef::Section::DebugTypes : DIERef::Section::DebugInfo;
+
+ llvm::Optional<uint32_t> dwo_num = uid >> 32 & 0x7fffffff;
+ if (*dwo_num == 0x7fffffff)
+ dwo_num = llvm::None;
+
+ return DecodedUID{*this, {dwo_num, section, die_offset}};
}
DWARFDIE
-SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) {
+SymbolFileDWARF::GetDIE(lldb::user_id_t uid) {
// This method can be called without going through the symbol vendor so we
// need to lock the module.
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we
- // must make sure we use the correct DWARF file when resolving things. On
- // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
- // SymbolFileDWARF classes, one for each .o file. We can often end up with
- // references to other DWARF objects and we must be ready to receive a
- // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
- // instance.
- SymbolFileDWARF *dwarf = GetDWARFForUID(uid);
- if (dwarf)
- return dwarf->GetDIE(DIERef(uid, dwarf));
+
+ llvm::Optional<DecodedUID> decoded = DecodeUID(uid);
+
+ if (decoded)
+ return decoded->dwarf.GetDIE(decoded->ref);
+
return DWARFDIE();
}
@@ -1354,10 +1259,9 @@ CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) {
// need to lock the module.
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
- // SymbolFileDWARF::GetDIEFromUID(). See comments inside the
- // SymbolFileDWARF::GetDIEFromUID() for details.
- DWARFDIE die = GetDIEFromUID(type_uid);
- if (die)
+ // SymbolFileDWARF::GetDIE(). See comments inside the
+ // SymbolFileDWARF::GetDIE() for details.
+ if (DWARFDIE die = GetDIE(type_uid))
return die.GetDecl();
return CompilerDecl();
}
@@ -1368,10 +1272,9 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
// need to lock the module.
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
- // SymbolFileDWARF::GetDIEFromUID(). See comments inside the
- // SymbolFileDWARF::GetDIEFromUID() for details.
- DWARFDIE die = GetDIEFromUID(type_uid);
- if (die)
+ // SymbolFileDWARF::GetDIE(). See comments inside the
+ // SymbolFileDWARF::GetDIE() for details.
+ if (DWARFDIE die = GetDIE(type_uid))
return die.GetDeclContext();
return CompilerDeclContext();
}
@@ -1382,10 +1285,9 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
// need to lock the module.
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
- // SymbolFileDWARF::GetDIEFromUID(). See comments inside the
- // SymbolFileDWARF::GetDIEFromUID() for details.
- DWARFDIE die = GetDIEFromUID(type_uid);
- if (die)
+ // SymbolFileDWARF::GetDIE(). See comments inside the
+ // SymbolFileDWARF::GetDIE() for details.
+ if (DWARFDIE die = GetDIE(type_uid))
return die.GetContainingDeclContext();
return CompilerDeclContext();
}
@@ -1395,10 +1297,9 @@ Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
// need to lock the module.
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
- // SymbolFileDWARF::GetDIEFromUID(). See comments inside the
- // SymbolFileDWARF::GetDIEFromUID() for details.
- DWARFDIE type_die = GetDIEFromUID(type_uid);
- if (type_die)
+ // SymbolFileDWARF::GetDIE(). See comments inside the
+ // SymbolFileDWARF::GetDIE() for details.
+ if (DWARFDIE type_die = GetDIE(type_uid))
return type_die.ResolveType();
else
return nullptr;
@@ -1408,8 +1309,7 @@ llvm::Optional<SymbolFile::ArrayInfo>
SymbolFileDWARF::GetDynamicArrayInfoForUID(
lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- DWARFDIE type_die = GetDIEFromUID(type_uid);
- if (type_die)
+ if (DWARFDIE type_die = GetDIE(type_uid))
return DWARFASTParser::ParseChildArrayInfo(type_die, exe_ctx);
else
return llvm::None;
@@ -1454,7 +1354,7 @@ Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,
}
return ResolveType(die);
}
- return NULL;
+ return nullptr;
}
// This function is used when SymbolFileDWARFDebugMap owns a bunch of
@@ -1548,15 +1448,14 @@ Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die,
}
CompileUnit *
-SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFUnit *dwarf_cu,
- uint32_t cu_idx) {
+SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu) {
// Check if the symbol vendor already knows about this compile unit?
- if (dwarf_cu->GetUserData() == NULL) {
+ if (dwarf_cu.GetUserData() == nullptr) {
// The symbol vendor doesn't know about this compile unit, we need to parse
// and add it to the symbol vendor object.
- return ParseCompileUnit(dwarf_cu, cu_idx).get();
+ return ParseCompileUnit(dwarf_cu).get();
}
- return (CompileUnit *)dwarf_cu->GetUserData();
+ return (CompileUnit *)dwarf_cu.GetUserData();
}
size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name,
@@ -1569,12 +1468,13 @@ size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name,
bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) {
sc.Clear(false);
- if (die) {
+ if (die && llvm::isa<DWARFCompileUnit>(die.GetCU())) {
// Check if the symbol vendor already knows about this compile unit?
- sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
+ sc.comp_unit =
+ GetCompUnitForDWARFCompUnit(llvm::cast<DWARFCompileUnit>(*die.GetCU()));
sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
- if (sc.function == NULL)
+ if (sc.function == nullptr)
sc.function = ParseFunction(*sc.comp_unit, die);
if (sc.function) {
@@ -1597,6 +1497,14 @@ lldb::ModuleSP SymbolFileDWARF::GetDWOModule(ConstString name) {
DWARFDIE
SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
+ if (die_ref.dwo_num()) {
+ return DebugInfo()
+ ->GetUnitAtIndex(*die_ref.dwo_num())
+ ->GetDwoSymbolFile()
+ ->GetDIE(die_ref);
+ }
+
+
DWARFDebugInfo *debug_info = DebugInfo();
if (debug_info)
return debug_info->GetDIE(die_ref);
@@ -1606,24 +1514,29 @@ SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
std::unique_ptr<SymbolFileDWARFDwo>
SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
- DWARFUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) {
+ DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) {
// If we are using a dSYM file, we never want the standard DWO files since
// the -gmodules support uses the same DWO machanism to specify full debug
// info files for modules.
if (GetDebugMapSymfile())
return nullptr;
- const char *dwo_name = cu_die.GetAttributeValueAsString(
- this, &dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
+ DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit);
+ // Only compile units can be split into two parts.
+ if (!dwarf_cu)
+ return nullptr;
+
+ const char *dwo_name =
+ cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
if (!dwo_name)
return nullptr;
SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile();
if (dwp_symfile) {
- uint64_t dwo_id = cu_die.GetAttributeValueAsUnsigned(this, &dwarf_cu,
- DW_AT_GNU_dwo_id, 0);
+ uint64_t dwo_id =
+ cu_die.GetAttributeValueAsUnsigned(dwarf_cu, DW_AT_GNU_dwo_id, 0);
std::unique_ptr<SymbolFileDWARFDwo> dwo_symfile =
- dwp_symfile->GetSymbolFileForDwoId(&dwarf_cu, dwo_id);
+ dwp_symfile->GetSymbolFileForDwoId(*dwarf_cu, dwo_id);
if (dwo_symfile)
return dwo_symfile;
}
@@ -1631,8 +1544,8 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
FileSpec dwo_file(dwo_name);
FileSystem::Instance().Resolve(dwo_file);
if (dwo_file.IsRelative()) {
- const char *comp_dir = cu_die.GetAttributeValueAsString(
- this, &dwarf_cu, DW_AT_comp_dir, nullptr);
+ const char *comp_dir =
+ cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_comp_dir, nullptr);
if (!comp_dir)
return nullptr;
@@ -1654,7 +1567,7 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
if (dwo_obj_file == nullptr)
return nullptr;
- return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, &dwarf_cu);
+ return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu);
}
void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
@@ -1666,7 +1579,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
const uint32_t num_compile_units = GetNumCompileUnits();
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
- DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ DWARFUnit *dwarf_cu = debug_info->GetUnitAtIndex(cu_idx);
const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly();
if (die && !die.HasChildren()) {
@@ -1708,16 +1621,14 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
// printed. However, as one can notice in this case we don't
// actually need to try to load the already loaded module
// (corresponding to .dwo) so we simply skip it.
- if (m_obj_file->GetFileSpec()
- .GetFileNameExtension()
- .GetStringRef() == ".dwo" &&
+ if (m_obj_file->GetFileSpec().GetFileNameExtension() == ".dwo" &&
llvm::StringRef(m_obj_file->GetFileSpec().GetPath())
.endswith(dwo_module_spec.GetFileSpec().GetPath())) {
continue;
}
Status error = ModuleList::GetSharedModule(
- dwo_module_spec, module_sp, NULL, NULL, NULL);
+ dwo_module_spec, module_sp, nullptr, nullptr, nullptr);
if (!module_sp) {
GetObjectFile()->GetModule()->ReportWarning(
"0x%8.8x: unable to locate module needed for external types: "
@@ -1737,8 +1648,8 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
}
SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
- if (!m_global_aranges_ap) {
- m_global_aranges_ap.reset(new GlobalVariableMap());
+ if (!m_global_aranges_up) {
+ m_global_aranges_up.reset(new GlobalVariableMap());
ModuleSP module_sp = GetObjectFile()->GetModule();
if (module_sp) {
@@ -1763,8 +1674,9 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
location_result.GetScalar().ULongLong();
lldb::addr_t byte_size = 1;
if (var_sp->GetType())
- byte_size = var_sp->GetType()->GetByteSize();
- m_global_aranges_ap->Append(GlobalVariableMap::Entry(
+ byte_size =
+ var_sp->GetType()->GetByteSize().getValueOr(0);
+ m_global_aranges_up->Append(GlobalVariableMap::Entry(
file_addr, byte_size, var_sp.get()));
}
}
@@ -1774,9 +1686,9 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
}
}
}
- m_global_aranges_ap->Sort();
+ m_global_aranges_up->Sort();
}
- return *m_global_aranges_ap;
+ return *m_global_aranges_up;
}
uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
@@ -1798,8 +1710,17 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
DWARFDebugInfo *debug_info = DebugInfo();
if (debug_info) {
- const dw_offset_t cu_offset =
- debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
+ llvm::Expected<DWARFDebugAranges &> aranges =
+ debug_info->GetCompileUnitAranges();
+ if (!aranges) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ LLDB_LOG_ERROR(log, aranges.takeError(),
+ "SymbolFileDWARF::ResolveSymbolContext failed to get cu "
+ "aranges. {0}");
+ return 0;
+ }
+
+ const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr);
if (cu_offset == DW_INVALID_OFFSET) {
// Global variables are not in the compile unit address ranges. The
// only way to currently find global variables is to iterate over the
@@ -1822,10 +1743,10 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
}
} else {
uint32_t cu_idx = DW_INVALID_INDEX;
- DWARFUnit *dwarf_cu =
- debug_info->GetCompileUnit(cu_offset, &cu_idx);
- if (dwarf_cu) {
- sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
+ if (auto *dwarf_cu = llvm::dyn_cast_or_null<DWARFCompileUnit>(
+ debug_info->GetUnitAtOffset(DIERef::Section::DebugInfo,
+ cu_offset, &cu_idx))) {
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
if (sc.comp_unit) {
resolved |= eSymbolContextCompUnit;
@@ -1837,7 +1758,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
if (function_die) {
sc.function =
sc.comp_unit->FindFunctionByUID(function_die.GetID()).get();
- if (sc.function == NULL)
+ if (sc.function == nullptr)
sc.function = ParseFunction(*sc.comp_unit, function_die);
if (sc.function && (resolve_scope & eSymbolContextBlock))
@@ -1852,7 +1773,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
force_check_line_table = true;
}
- if (sc.function != NULL) {
+ if (sc.function != nullptr) {
resolved |= eSymbolContextFunction;
if (resolve_scope & eSymbolContextBlock) {
@@ -1871,7 +1792,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
if ((resolve_scope & eSymbolContextLineEntry) ||
force_check_line_table) {
LineTable *line_table = sc.comp_unit->GetLineTable();
- if (line_table != NULL) {
+ if (line_table != nullptr) {
// And address that makes it into this function should be in
// terms of this debug file if there is no debug map, or it
// will be an address in the .o file which needs to be fixed up
@@ -1895,7 +1816,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
// only happen when there aren't other functions from other
// compile units in these gaps. This helps keep the size of the
// aranges down.
- sc.comp_unit = NULL;
+ sc.comp_unit = nullptr;
resolved &= ~eSymbolContextCompUnit;
}
} else {
@@ -1918,110 +1839,100 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
SymbolContextList &sc_list) {
const uint32_t prev_size = sc_list.GetSize();
if (resolve_scope & eSymbolContextCompUnit) {
- DWARFDebugInfo *debug_info = DebugInfo();
- if (debug_info) {
- uint32_t cu_idx;
- DWARFUnit *dwarf_cu = NULL;
-
- for (cu_idx = 0;
- (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL;
- ++cu_idx) {
- CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
- const bool full_match = (bool)file_spec.GetDirectory();
- bool file_spec_matches_cu_file_spec =
- dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
- if (check_inlines || file_spec_matches_cu_file_spec) {
- SymbolContext sc(m_obj_file->GetModule());
- sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
- if (sc.comp_unit) {
- uint32_t file_idx = UINT32_MAX;
+ for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
+ ++cu_idx) {
+ CompileUnit *dc_cu = ParseCompileUnitAtIndex(cu_idx).get();
+ if (!dc_cu)
+ continue;
+
+ const bool full_match = (bool)file_spec.GetDirectory();
+ bool file_spec_matches_cu_file_spec =
+ FileSpec::Equal(file_spec, *dc_cu, full_match);
+ if (check_inlines || file_spec_matches_cu_file_spec) {
+ SymbolContext sc(m_obj_file->GetModule());
+ sc.comp_unit = dc_cu;
+ uint32_t file_idx = UINT32_MAX;
+
+ // If we are looking for inline functions only and we don't find it
+ // in the support files, we are done.
+ if (check_inlines) {
+ file_idx =
+ sc.comp_unit->GetSupportFiles().FindFileIndex(1, file_spec, true);
+ if (file_idx == UINT32_MAX)
+ continue;
+ }
- // If we are looking for inline functions only and we don't find it
- // in the support files, we are done.
- if (check_inlines) {
+ if (line != 0) {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+
+ if (line_table != nullptr && line != 0) {
+ // We will have already looked up the file index if we are
+ // searching for inline entries.
+ if (!check_inlines)
file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
1, file_spec, true);
- if (file_idx == UINT32_MAX)
- continue;
- }
-
- if (line != 0) {
- LineTable *line_table = sc.comp_unit->GetLineTable();
- if (line_table != NULL && line != 0) {
- // We will have already looked up the file index if we are
- // searching for inline entries.
- if (!check_inlines)
- file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
- 1, file_spec, true);
-
- if (file_idx != UINT32_MAX) {
- uint32_t found_line;
- uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex(
- 0, file_idx, line, false, &sc.line_entry);
- found_line = sc.line_entry.line;
-
- while (line_idx != UINT32_MAX) {
- sc.function = NULL;
- sc.block = NULL;
- if (resolve_scope &
- (eSymbolContextFunction | eSymbolContextBlock)) {
- const lldb::addr_t file_vm_addr =
- sc.line_entry.range.GetBaseAddress().GetFileAddress();
- if (file_vm_addr != LLDB_INVALID_ADDRESS) {
- DWARFDIE function_die =
- dwarf_cu->LookupAddress(file_vm_addr);
- DWARFDIE block_die;
- if (function_die) {
- sc.function =
- sc.comp_unit
- ->FindFunctionByUID(function_die.GetID())
- .get();
- if (sc.function == NULL)
- sc.function =
- ParseFunction(*sc.comp_unit, function_die);
-
- if (sc.function &&
- (resolve_scope & eSymbolContextBlock))
- block_die =
- function_die.LookupDeepestBlock(file_vm_addr);
- }
+ if (file_idx != UINT32_MAX) {
+ uint32_t found_line;
+ uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex(
+ 0, file_idx, line, false, &sc.line_entry);
+ found_line = sc.line_entry.line;
+
+ while (line_idx != UINT32_MAX) {
+ sc.function = nullptr;
+ sc.block = nullptr;
+ if (resolve_scope &
+ (eSymbolContextFunction | eSymbolContextBlock)) {
+ const lldb::addr_t file_vm_addr =
+ sc.line_entry.range.GetBaseAddress().GetFileAddress();
+ if (file_vm_addr != LLDB_INVALID_ADDRESS) {
+ DWARFDIE function_die =
+ GetDWARFCompileUnit(dc_cu)->LookupAddress(file_vm_addr);
+ DWARFDIE block_die;
+ if (function_die) {
+ sc.function =
+ sc.comp_unit->FindFunctionByUID(function_die.GetID())
+ .get();
+ if (sc.function == nullptr)
+ sc.function =
+ ParseFunction(*sc.comp_unit, function_die);
+
+ if (sc.function && (resolve_scope & eSymbolContextBlock))
+ block_die =
+ function_die.LookupDeepestBlock(file_vm_addr);
+ }
- if (sc.function != NULL) {
- Block &block = sc.function->GetBlock(true);
+ if (sc.function != nullptr) {
+ Block &block = sc.function->GetBlock(true);
- if (block_die)
- sc.block = block.FindBlockByID(block_die.GetID());
- else if (function_die)
- sc.block =
- block.FindBlockByID(function_die.GetID());
- }
- }
+ if (block_die)
+ sc.block = block.FindBlockByID(block_die.GetID());
+ else if (function_die)
+ sc.block = block.FindBlockByID(function_die.GetID());
}
-
- sc_list.Append(sc);
- line_idx = line_table->FindLineEntryIndexByFileIndex(
- line_idx + 1, file_idx, found_line, true,
- &sc.line_entry);
}
}
- } else if (file_spec_matches_cu_file_spec && !check_inlines) {
- // only append the context if we aren't looking for inline call
- // sites by file and line and if the file spec matches that of
- // the compile unit
+
sc_list.Append(sc);
+ line_idx = line_table->FindLineEntryIndexByFileIndex(
+ line_idx + 1, file_idx, found_line, true, &sc.line_entry);
}
- } else if (file_spec_matches_cu_file_spec && !check_inlines) {
- // only append the context if we aren't looking for inline call
- // sites by file and line and if the file spec matches that of
- // the compile unit
- sc_list.Append(sc);
}
-
- if (!check_inlines)
- break;
+ } else if (file_spec_matches_cu_file_spec && !check_inlines) {
+ // only append the context if we aren't looking for inline call
+ // sites by file and line and if the file spec matches that of
+ // the compile unit
+ sc_list.Append(sc);
}
+ } else if (file_spec_matches_cu_file_spec && !check_inlines) {
+ // only append the context if we aren't looking for inline call
+ // sites by file and line and if the file spec matches that of
+ // the compile unit
+ sc_list.Append(sc);
}
+
+ if (!check_inlines)
+ break;
}
}
}
@@ -2066,7 +1977,7 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
}
uint32_t SymbolFileDWARF::FindGlobalVariables(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
@@ -2082,7 +1993,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
return 0;
DWARFDebugInfo *info = DebugInfo();
- if (info == NULL)
+ if (info == nullptr)
return 0;
// Remember how many variables are in the list before we search.
@@ -2090,6 +2001,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
llvm::StringRef basename;
llvm::StringRef context;
+ bool name_is_mangled = (bool)Mangled(name);
if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name.GetCString(),
context, basename))
@@ -2122,7 +2034,10 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
break;
case DW_TAG_variable: {
- sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
+ auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
+ if (!dwarf_cu)
+ continue;
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
if (parent_decl_ctx) {
DWARFASTParser *dwarf_ast = die.GetDWARFParser();
@@ -2139,7 +2054,8 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
&variables);
while (pruned_idx < variables.GetSize()) {
VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx);
- if (var_sp->GetName().GetStringRef().contains(name.GetStringRef()))
+ if (name_is_mangled ||
+ var_sp->GetName().GetStringRef().contains(name.GetStringRef()))
++pruned_idx;
else
variables.RemoveVariableAtIndex(pruned_idx);
@@ -2150,8 +2066,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
} break;
}
} else {
- m_index->ReportInvalidDIEOffset(die_ref.die_offset,
- name.GetStringRef());
+ m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
}
}
}
@@ -2183,7 +2098,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
}
DWARFDebugInfo *info = DebugInfo();
- if (info == NULL)
+ if (info == nullptr)
return 0;
// Remember how many variables are in the list before we search.
@@ -2203,14 +2118,18 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
DWARFDIE die = GetDIE(die_ref);
if (die) {
- sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
+ DWARFCompileUnit *dwarf_cu =
+ llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
+ if (!dwarf_cu)
+ continue;
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
if (variables.GetSize() - original_size >= max_matches)
break;
} else
- m_index->ReportInvalidDIEOffset(die_ref.die_offset, regex.GetText());
+ m_index->ReportInvalidDIERef(die_ref, regex.GetText());
}
}
@@ -2236,7 +2155,7 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
if (die.Tag() == DW_TAG_inlined_subroutine) {
inlined_die = die;
- while (1) {
+ while (true) {
die = die.GetParent();
if (die) {
@@ -2253,12 +2172,12 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
if (inlined_die) {
Block &function_block = sc.function->GetBlock(true);
sc.block = function_block.FindBlockByID(inlined_die.GetID());
- if (sc.block == NULL)
+ if (sc.block == nullptr)
sc.block = function_block.FindBlockByID(inlined_die.GetOffset());
- if (sc.block == NULL || !sc.block->GetStartAddress(addr))
+ if (sc.block == nullptr || !sc.block->GetStartAddress(addr))
addr.Clear();
} else {
- sc.block = NULL;
+ sc.block = nullptr;
addr = sc.function->GetAddressRange().GetBaseAddress();
}
@@ -2285,14 +2204,14 @@ bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx,
CompilerDeclContext actual_decl_ctx =
dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
if (actual_decl_ctx)
- return actual_decl_ctx == *decl_ctx;
+ return decl_ctx->IsContainedInLookup(actual_decl_ctx);
}
}
return false;
}
uint32_t SymbolFileDWARF::FindFunctions(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
FunctionNameType name_type_mask, bool include_inlines, bool append,
SymbolContextList &sc_list) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
@@ -2328,10 +2247,6 @@ uint32_t SymbolFileDWARF::FindFunctions(
const uint32_t original_size = sc_list.GetSize();
- DWARFDebugInfo *info = DebugInfo();
- if (info == NULL)
- return 0;
-
llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
DIEArray offsets;
CompilerDeclContext empty_decl_ctx;
@@ -2339,7 +2254,7 @@ uint32_t SymbolFileDWARF::FindFunctions(
parent_decl_ctx = &empty_decl_ctx;
std::vector<DWARFDIE> dies;
- m_index->GetFunctions(name, *info, *parent_decl_ctx, name_type_mask, dies);
+ m_index->GetFunctions(name, *this, *parent_decl_ctx, name_type_mask, dies);
for (const DWARFDIE &die: dies) {
if (resolved_dies.insert(die.GetDIE()).second)
ResolveFunction(die, include_inlines, sc_list);
@@ -2394,7 +2309,7 @@ uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
for (DIERef ref : offsets) {
DWARFDIE die = info->GetDIE(ref);
if (!die) {
- m_index->ReportInvalidDIEOffset(ref.die_offset, regex.GetText());
+ m_index->ReportInvalidDIERef(ref, regex.GetText());
continue;
}
if (resolved_dies.insert(die.GetDIE()).second)
@@ -2411,10 +2326,10 @@ void SymbolFileDWARF::GetMangledNamesForFunction(
DWARFDebugInfo *info = DebugInfo();
uint32_t num_comp_units = 0;
if (info)
- num_comp_units = info->GetNumCompileUnits();
+ num_comp_units = info->GetNumUnits();
for (uint32_t i = 0; i < num_comp_units; i++) {
- DWARFUnit *cu = info->GetCompileUnitAtIndex(i);
+ DWARFUnit *cu = info->GetUnitAtIndex(i);
if (cu == nullptr)
continue;
@@ -2423,21 +2338,15 @@ void SymbolFileDWARF::GetMangledNamesForFunction(
dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names);
}
- NameToOffsetMap::iterator iter =
- m_function_scope_qualified_name_map.find(scope_qualified_name);
- if (iter == m_function_scope_qualified_name_map.end())
- return;
-
- DIERefSetSP set_sp = (*iter).second;
- std::set<DIERef>::iterator set_iter;
- for (set_iter = set_sp->begin(); set_iter != set_sp->end(); set_iter++) {
- DWARFDIE die = DebugInfo()->GetDIE(*set_iter);
+ for (lldb::user_id_t uid :
+ m_function_scope_qualified_name_map.lookup(scope_qualified_name)) {
+ DWARFDIE die = GetDIE(uid);
mangled_names.push_back(ConstString(die.GetMangledName()));
}
}
uint32_t SymbolFileDWARF::FindTypes(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
bool append, uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
@@ -2452,7 +2361,7 @@ uint32_t SymbolFileDWARF::FindTypes(
searched_symbol_files.insert(this);
DWARFDebugInfo *info = DebugInfo();
- if (info == NULL)
+ if (info == nullptr)
return 0;
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
@@ -2497,8 +2406,7 @@ uint32_t SymbolFileDWARF::FindTypes(
break;
}
} else {
- m_index->ReportInvalidDIEOffset(die_ref.die_offset,
- name.GetStringRef());
+ m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
}
}
const uint32_t num_matches = types.GetSize() - initial_types_size;
@@ -2576,8 +2484,7 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context,
++num_matches;
}
} else {
- m_index->ReportInvalidDIEOffset(die_ref.die_offset,
- name.GetStringRef());
+ m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
}
}
return num_matches;
@@ -2586,7 +2493,7 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context,
}
CompilerDeclContext
-SymbolFileDWARF::FindNamespace(const ConstString &name,
+SymbolFileDWARF::FindNamespace(ConstString name,
const CompilerDeclContext *parent_decl_ctx) {
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
@@ -2622,8 +2529,7 @@ SymbolFileDWARF::FindNamespace(const ConstString &name,
break;
}
} else {
- m_index->ReportInvalidDIEOffset(die_ref.die_offset,
- name.GetStringRef());
+ m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
}
}
}
@@ -2646,10 +2552,14 @@ TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die,
TypeSP type_sp;
if (die) {
Type *type_ptr = GetDIEToType().lookup(die.GetDIE());
- if (type_ptr == NULL) {
- CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
- assert(lldb_cu);
- SymbolContext sc(lldb_cu);
+ if (type_ptr == nullptr) {
+ SymbolContextScope *scope;
+ if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()))
+ scope = GetCompUnitForDWARFCompUnit(*dwarf_cu);
+ else
+ scope = GetObjectFile()->GetModule().get();
+ assert(scope);
+ SymbolContext sc(scope);
const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE();
while (parent_die != nullptr) {
if (parent_die->Tag() == DW_TAG_subprogram)
@@ -2661,7 +2571,7 @@ TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die,
!GetFunction(DWARFDIE(die.GetCU(), parent_die), sc))
sc = sc_backup;
- type_sp = ParseType(sc, die, NULL);
+ type_sp = ParseType(sc, die, nullptr);
} else if (type_ptr != DIE_IS_BEING_PARSED) {
// Grab the existing type from the master types lists
type_sp = type_ptr->shared_from_this();
@@ -2723,8 +2633,8 @@ SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) {
}
Symbol *
-SymbolFileDWARF::GetObjCClassSymbol(const ConstString &objc_class_name) {
- Symbol *objc_class_symbol = NULL;
+SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {
+ Symbol *objc_class_symbol = nullptr;
if (m_obj_file) {
Symtab *symtab = m_obj_file->GetSymtab();
if (symtab) {
@@ -2753,7 +2663,7 @@ bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(
DWARFDebugInfo *debug_info = DebugInfo();
const uint32_t num_compile_units = GetNumCompileUnits();
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
- DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ DWARFUnit *dwarf_cu = debug_info->GetUnitAtIndex(cu_idx);
if (dwarf_cu != cu &&
dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type()) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
@@ -2771,7 +2681,7 @@ bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(
// This function can be used when a DIE is found that is a forward declaration
// DIE and we want to try and find a type that has the complete definition.
TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
- const DWARFDIE &die, const ConstString &type_name,
+ const DWARFDIE &die, ConstString type_name,
bool must_be_implementation) {
TypeSP type_sp;
@@ -2829,15 +2739,13 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
}
}
} else {
- m_index->ReportInvalidDIEOffset(die_ref.die_offset,
- type_name.GetStringRef());
+ m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef());
}
}
}
return type_sp;
}
-//----------------------------------------------------------------------
// This function helps to ensure that the declaration contexts match for two
// different DIEs. Often times debug information will refer to a forward
// declaration of a type (the equivalent of "struct my_struct;". There will
@@ -2847,14 +2755,13 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
// type was in the same declaration context as the original DIE. This function
// can efficiently compare two DIEs and will return true when the declaration
// context matches, and false when they don't.
-//----------------------------------------------------------------------
bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1,
const DWARFDIE &die2) {
if (die1 == die2)
return true;
- DWARFDIECollection decl_ctx_1;
- DWARFDIECollection decl_ctx_2;
+ std::vector<DWARFDIE> decl_ctx_1;
+ std::vector<DWARFDIE> decl_ctx_2;
// The declaration DIE stack is a stack of the declaration context DIEs all
// the way back to the compile unit. If a type "T" is declared inside a class
// "B", and class "B" is declared inside a class "A" and class "A" is in a
@@ -2870,11 +2777,11 @@ bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1,
// back to the compiler unit.
// First lets grab the decl contexts for both DIEs
- die1.GetDeclContextDIEs(decl_ctx_1);
- die2.GetDeclContextDIEs(decl_ctx_2);
+ decl_ctx_1 = die1.GetDeclContextDIEs();
+ decl_ctx_2 = die2.GetDeclContextDIEs();
// Make sure the context arrays have the same size, otherwise we are done
- const size_t count1 = decl_ctx_1.Size();
- const size_t count2 = decl_ctx_2.Size();
+ const size_t count1 = decl_ctx_1.size();
+ const size_t count2 = decl_ctx_2.size();
if (count1 != count2)
return false;
@@ -2884,18 +2791,18 @@ bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1,
DWARFDIE decl_ctx_die2;
size_t i;
for (i = 0; i < count1; i++) {
- decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex(i);
- decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex(i);
+ decl_ctx_die1 = decl_ctx_1[i];
+ decl_ctx_die2 = decl_ctx_2[i];
if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag())
return false;
}
-#if defined LLDB_CONFIGURATION_DEBUG
+#ifndef NDEBUG
// Make sure the top item in the decl context die array is always
// DW_TAG_compile_unit or DW_TAG_partial_unit. If it isn't then
// something went wrong in the DWARFDIE::GetDeclContextDIEs()
// function.
- dw_tag_t cu_tag = decl_ctx_1.GetDIEAtIndex(count1 - 1).Tag();
+ dw_tag_t cu_tag = decl_ctx_1[count1 - 1].Tag();
UNUSED_IF_ASSERT_DISABLED(cu_tag);
assert(cu_tag == DW_TAG_compile_unit || cu_tag == DW_TAG_partial_unit);
@@ -2903,8 +2810,8 @@ bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1,
// Always skip the compile unit when comparing by only iterating up to "count
// - 1". Here we compare the names as we go.
for (i = 0; i < count1 - 1; i++) {
- decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex(i);
- decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex(i);
+ decl_ctx_die1 = decl_ctx_1[i];
+ decl_ctx_die2 = decl_ctx_2[i];
const char *name1 = decl_ctx_die1.GetName();
const char *name2 = decl_ctx_die2.GetName();
// If the string was from a DW_FORM_strp, then the pointer will often be
@@ -3039,8 +2946,7 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
}
}
} else {
- m_index->ReportInvalidDIEOffset(die_ref.die_offset,
- type_name.GetStringRef());
+ m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef());
}
}
}
@@ -3051,42 +2957,32 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
bool *type_is_new_ptr) {
- TypeSP type_sp;
+ if (!die)
+ return {};
- if (die) {
- TypeSystem *type_system =
- GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
+ TypeSystem *type_system =
+ GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
+ if (!type_system)
+ return {};
- if (type_system) {
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
- if (dwarf_ast) {
- Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
- type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr);
- if (type_sp) {
- TypeList *type_list = GetTypeList();
- if (type_list)
- type_list->Insert(type_sp);
-
- if (die.Tag() == DW_TAG_subprogram) {
- DIERef die_ref = die.GetDIERef();
- std::string scope_qualified_name(GetDeclContextForUID(die.GetID())
- .GetScopeQualifiedName()
- .AsCString(""));
- if (scope_qualified_name.size()) {
- NameToOffsetMap::iterator iter =
- m_function_scope_qualified_name_map.find(
- scope_qualified_name);
- if (iter != m_function_scope_qualified_name_map.end())
- (*iter).second->insert(die_ref);
- else {
- DIERefSetSP new_set(new std::set<DIERef>);
- new_set->insert(die_ref);
- m_function_scope_qualified_name_map.emplace(
- std::make_pair(scope_qualified_name, new_set));
- }
- }
- }
- }
+ DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+ if (!dwarf_ast)
+ return {};
+
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr);
+ if (type_sp) {
+ TypeList *type_list = GetTypeList();
+ if (type_list)
+ type_list->Insert(type_sp);
+
+ if (die.Tag() == DW_TAG_subprogram) {
+ std::string scope_qualified_name(GetDeclContextForUID(die.GetID())
+ .GetScopeQualifiedName()
+ .AsCString(""));
+ if (scope_qualified_name.size()) {
+ m_function_scope_qualified_name_map[scope_qualified_name].insert(
+ die.GetID());
}
}
}
@@ -3161,13 +3057,13 @@ size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {
size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
ASSERT_MODULE_LOCK(this);
- if (sc.comp_unit != NULL) {
+ if (sc.comp_unit != nullptr) {
DWARFDebugInfo *info = DebugInfo();
- if (info == NULL)
+ if (info == nullptr)
return 0;
if (sc.function) {
- DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID(), this));
+ DWARFDIE function_die = GetDIE(sc.function->GetID());
const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress(
DW_AT_low_pc, LLDB_INVALID_ADDRESS);
@@ -3180,20 +3076,21 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
return num_variables;
}
} else if (sc.comp_unit) {
- DWARFUnit *dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
+ DWARFUnit *dwarf_cu = info->GetUnitAtIndex(sc.comp_unit->GetID());
- if (dwarf_cu == NULL)
+ if (dwarf_cu == nullptr)
return 0;
uint32_t vars_added = 0;
VariableListSP variables(sc.comp_unit->GetVariableList(false));
- if (variables.get() == NULL) {
- variables.reset(new VariableList());
+ if (variables.get() == nullptr) {
+ variables = std::make_shared<VariableList>();
sc.comp_unit->SetVariableList(variables);
DIEArray die_offsets;
- m_index->GetGlobalVariables(*dwarf_cu, die_offsets);
+ m_index->GetGlobalVariables(dwarf_cu->GetNonSkeletonUnit(),
+ die_offsets);
const size_t num_matches = die_offsets.size();
if (num_matches) {
for (size_t i = 0; i < num_matches; ++i) {
@@ -3207,7 +3104,7 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
++vars_added;
}
} else
- m_index->ReportInvalidDIEOffset(die_ref.die_offset, "");
+ m_index->ReportInvalidDIERef(die_ref, "");
}
}
}
@@ -3240,12 +3137,12 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
const size_t num_attributes = die.GetAttributes(attributes);
DWARFDIE spec_die;
if (num_attributes > 0) {
- const char *name = NULL;
- const char *mangled = NULL;
+ const char *name = nullptr;
+ const char *mangled = nullptr;
Declaration decl;
uint32_t i;
DWARFFormValue type_die_form;
- DWARFExpression location(die.GetCU());
+ DWARFExpression location;
bool is_external = false;
bool is_artificial = false;
bool location_is_const_value_data = false;
@@ -3296,18 +3193,16 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- location.CopyOpcodeData(module, debug_info_data, block_offset,
- block_length);
+ location = DWARFExpression(module, debug_info_data, die.GetCU(),
+ block_offset, block_length);
} else if (DWARFFormValue::IsDataForm(form_value.Form())) {
// Retrieve the value as a data expression.
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize(
- attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
- attributes.CompileUnitAtIndex(i)->IsDWARF64());
uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
- uint32_t data_length =
- fixed_form_sizes.GetSize(form_value.Form());
- if (data_length == 0) {
+ if (auto data_length = form_value.GetFixedSize())
+ location =
+ DWARFExpression(module, debug_info_data, die.GetCU(),
+ data_offset, *data_length);
+ else {
const uint8_t *data_pointer = form_value.BlockData();
if (data_pointer) {
form_value.Unsigned();
@@ -3316,29 +3211,23 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
// create the variable
const_value = form_value;
}
- } else
- location.CopyOpcodeData(module, debug_info_data, data_offset,
- data_length);
+ }
} else {
// Retrieve the value as a string expression.
if (form_value.Form() == DW_FORM_strp) {
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize(
- attributes.CompileUnitAtIndex(i)
- ->GetAddressByteSize(),
- attributes.CompileUnitAtIndex(i)->IsDWARF64());
uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
- uint32_t data_length =
- fixed_form_sizes.GetSize(form_value.Form());
- location.CopyOpcodeData(module, debug_info_data, data_offset,
- data_length);
+ if (auto data_length = form_value.GetFixedSize())
+ location =
+ DWARFExpression(module, debug_info_data, die.GetCU(),
+ data_offset, *data_length);
} else {
const char *str = form_value.AsCString();
uint32_t string_offset =
str - (const char *)debug_info_data.GetDataStart();
uint32_t string_length = strlen(str) + 1;
- location.CopyOpcodeData(module, debug_info_data,
- string_offset, string_length);
+ location =
+ DWARFExpression(module, debug_info_data, die.GetCU(),
+ string_offset, string_length);
}
}
}
@@ -3352,7 +3241,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
uint32_t block_offset =
form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- location.CopyOpcodeData(module, data, block_offset, block_length);
+ location = DWARFExpression(module, data, die.GetCU(),
+ block_offset, block_length);
} else {
const DWARFDataExtractor &debug_loc_data = DebugLocData();
const dw_offset_t debug_loc_offset = form_value.Unsigned();
@@ -3360,8 +3250,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
size_t loc_list_length = DWARFExpression::LocationListSize(
die.GetCU(), debug_loc_data, debug_loc_offset);
if (loc_list_length > 0) {
- location.CopyOpcodeData(module, debug_loc_data,
- debug_loc_offset, loc_list_length);
+ location = DWARFExpression(module, debug_loc_data, die.GetCU(),
+ debug_loc_offset, loc_list_length);
assert(func_low_pc != LLDB_INVALID_ADDRESS);
location.SetLocationListSlide(
func_low_pc -
@@ -3370,31 +3260,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
}
} break;
case DW_AT_specification:
- spec_die = GetDIE(DIERef(form_value));
+ spec_die = form_value.Reference();
+ break;
+ case DW_AT_start_scope:
+ // TODO: Implement this.
break;
- case DW_AT_start_scope: {
- if (form_value.Form() == DW_FORM_sec_offset) {
- DWARFRangeList dwarf_scope_ranges;
- const DWARFDebugRangesBase *debug_ranges = DebugRanges();
- debug_ranges->FindRanges(die.GetCU(),
- form_value.Unsigned(),
- dwarf_scope_ranges);
- } else {
- // TODO: Handle the case when DW_AT_start_scope have form
- // constant. The
- // dwarf spec is a bit ambiguous about what is the expected
- // behavior in case the enclosing block have a non coninious
- // address range and the DW_AT_start_scope entry have a form
- // constant.
- GetObjectFile()->GetModule()->ReportWarning(
- "0x%8.8" PRIx64
- ": DW_AT_start_scope has unsupported form type (0x%x)\n",
- die.GetID(), form_value.Form());
- }
-
- scope_ranges.Sort();
- scope_ranges.CombineConsecutiveRanges();
- } break;
case DW_AT_artificial:
is_artificial = form_value.Boolean();
break;
@@ -3425,7 +3295,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
ValueType scope = eValueTypeInvalid;
const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
- SymbolContextScope *symbol_context_scope = NULL;
+ SymbolContextScope *symbol_context_scope = nullptr;
bool has_explicit_mangled = mangled != nullptr;
if (!mangled) {
@@ -3471,7 +3341,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
if (op_error) {
StreamString strm;
location.DumpLocationForAddress(&strm, eDescriptionLevelFull, 0, 0,
- NULL);
+ nullptr);
GetObjectFile()->GetModule()->ReportError(
"0x%8.8x: %s has an invalid location: %s", die.GetOffset(),
die.GetTagAsCString(), strm.GetData());
@@ -3574,7 +3444,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
}
}
- if (symbol_context_scope == NULL) {
+ if (symbol_context_scope == nullptr) {
switch (parent_tag) {
case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
@@ -3582,7 +3452,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
if (sc.function) {
symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(
sc_parent_die.GetID());
- if (symbol_context_scope == NULL)
+ if (symbol_context_scope == nullptr)
symbol_context_scope = sc.function;
}
break;
@@ -3595,17 +3465,17 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
if (symbol_context_scope) {
SymbolFileTypeSP type_sp(
- new SymbolFileType(*this, DIERef(type_die_form).GetUID(this)));
+ new SymbolFileType(*this, GetUID(type_die_form.Reference())));
if (const_value.Form() && type_sp && type_sp->GetType())
- location.CopyOpcodeData(const_value.Unsigned(),
- type_sp->GetType()->GetByteSize(),
- die.GetCU()->GetAddressByteSize());
+ location.UpdateValue(const_value.Unsigned(),
+ type_sp->GetType()->GetByteSize().getValueOr(0),
+ die.GetCU()->GetAddressByteSize());
- var_sp.reset(new Variable(die.GetID(), name, mangled, type_sp, scope,
- symbol_context_scope, scope_ranges, &decl,
- location, is_external, is_artificial,
- is_static_member));
+ var_sp = std::make_shared<Variable>(
+ die.GetID(), name, mangled, type_sp, scope, symbol_context_scope,
+ scope_ranges, &decl, location, is_external, is_artificial,
+ is_static_member);
var_sp->SetLocationIsConstantValueData(location_is_const_value_data);
} else {
@@ -3644,12 +3514,11 @@ SymbolFileDWARF::FindBlockContainingSpecification(
case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
case DW_TAG_lexical_block: {
- if (die.GetAttributeValueAsReference(
- DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
+ if (die.GetReferencedDIE(DW_AT_specification).GetOffset() ==
+ spec_block_die_offset)
return die;
- if (die.GetAttributeValueAsReference(DW_AT_abstract_origin,
- DW_INVALID_OFFSET) ==
+ if (die.GetReferencedDIE(DW_AT_abstract_origin).GetOffset() ==
spec_block_die_offset)
return die;
} break;
@@ -3694,16 +3563,16 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
// We haven't already parsed it, lets do that now.
if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
(tag == DW_TAG_formal_parameter && sc.function)) {
- if (variable_list_sp.get() == NULL) {
+ if (variable_list_sp.get() == nullptr) {
DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
dw_tag_t parent_tag = sc_parent_die.Tag();
switch (parent_tag) {
case DW_TAG_compile_unit:
case DW_TAG_partial_unit:
- if (sc.comp_unit != NULL) {
+ if (sc.comp_unit != nullptr) {
variable_list_sp = sc.comp_unit->GetVariableList(false);
- if (variable_list_sp.get() == NULL) {
- variable_list_sp.reset(new VariableList());
+ if (variable_list_sp.get() == nullptr) {
+ variable_list_sp = std::make_shared<VariableList>();
}
} else {
GetObjectFile()->GetModule()->ReportError(
@@ -3718,31 +3587,31 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
case DW_TAG_lexical_block:
- if (sc.function != NULL) {
+ if (sc.function != nullptr) {
// Check to see if we already have parsed the variables for the
// given scope
Block *block = sc.function->GetBlock(true).FindBlockByID(
sc_parent_die.GetID());
- if (block == NULL) {
+ if (block == nullptr) {
// This must be a specification or abstract origin with a
// concrete block counterpart in the current function. We need
// to find the concrete block so we can correctly add the
// variable to it
const DWARFDIE concrete_block_die =
FindBlockContainingSpecification(
- DIERef(sc.function->GetID(), this),
+ GetDIE(sc.function->GetID()),
sc_parent_die.GetOffset());
if (concrete_block_die)
block = sc.function->GetBlock(true).FindBlockByID(
concrete_block_die.GetID());
}
- if (block != NULL) {
+ if (block != nullptr) {
const bool can_create = false;
variable_list_sp = block->GetBlockVariableList(can_create);
- if (variable_list_sp.get() == NULL) {
- variable_list_sp.reset(new VariableList());
+ if (variable_list_sp.get() == nullptr) {
+ variable_list_sp = std::make_shared<VariableList>();
block->SetVariableList(variable_list_sp);
}
}
@@ -3770,7 +3639,7 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
}
}
- bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
+ bool skip_children = (sc.function == nullptr && tag == DW_TAG_subprogram);
if (!skip_children && parse_children && die.HasChildren()) {
vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true,
@@ -3833,15 +3702,13 @@ CollectCallEdges(DWARFDIE function_die) {
std::vector<lldb_private::CallEdge>
SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) {
- DWARFDIE func_die = GetDIEFromUID(func_id.GetID());
+ DWARFDIE func_die = GetDIE(func_id.GetID());
if (func_die.IsValid())
return CollectCallEdges(func_die);
return {};
}
-//------------------------------------------------------------------
// PluginInterface protocol
-//------------------------------------------------------------------
ConstString SymbolFileDWARF::GetPluginName() { return GetPluginNameStatic(); }
uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; }
@@ -3857,7 +3724,7 @@ void SymbolFileDWARF::DumpClangAST(Stream &s) {
}
SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
- if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired()) {
+ if (m_debug_map_symfile == nullptr && !m_debug_map_module_wp.expired()) {
lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
if (module_sp) {
SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
@@ -3882,7 +3749,10 @@ SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() {
module_spec.GetFileSpec() = m_obj_file->GetFileSpec();
module_spec.GetSymbolFileSpec() =
FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp");
- FileSpec dwp_filespec = Symbols::LocateExecutableSymbolFile(module_spec);
+
+ FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
+ FileSpec dwp_filespec =
+ Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
if (FileSystem::Instance().Exists(dwp_filespec)) {
m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(),
dwp_filespec);
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index d351289f8b51..018af47305f4 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -1,9 +1,8 @@
//===-- SymbolFileDWARF.h --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -20,9 +19,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Threading.h"
-#include "lldb/Utility/Flags.h"
-
-#include "lldb/Core/RangeMap.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Expression/DWARFExpression.h"
@@ -30,20 +26,21 @@
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Flags.h"
+#include "lldb/Utility/RangeMap.h"
#include "lldb/lldb-private.h"
+#include "DWARFContext.h"
#include "DWARFDataExtractor.h"
#include "DWARFDefines.h"
#include "DWARFIndex.h"
#include "UniqueDWARFASTType.h"
-//----------------------------------------------------------------------
// Forward Declarations for this DWARF plugin
-//----------------------------------------------------------------------
class DebugMapModule;
class DWARFAbbreviationDeclaration;
class DWARFAbbreviationDeclarationSet;
-class DWARFileUnit;
+class DWARFCompileUnit;
class DWARFDebugAbbrev;
class DWARFDebugAranges;
class DWARFDebugInfo;
@@ -51,8 +48,8 @@ class DWARFDebugInfoEntry;
class DWARFDebugLine;
class DWARFDebugRangesBase;
class DWARFDeclContext;
-class DWARFDIECollection;
class DWARFFormValue;
+class DWARFTypeUnit;
class SymbolFileDWARFDebugMap;
class SymbolFileDWARFDwo;
class SymbolFileDWARFDwp;
@@ -65,14 +62,11 @@ public:
friend class SymbolFileDWARFDebugMap;
friend class SymbolFileDWARFDwo;
friend class DebugMapModule;
- friend struct DIERef;
- friend class DWARFUnit;
+ friend class DWARFCompileUnit;
friend class DWARFDIE;
friend class DWARFASTParserClang;
- //------------------------------------------------------------------
// Static Functions
- //------------------------------------------------------------------
static void Initialize();
static void Terminate();
@@ -86,11 +80,12 @@ public:
static lldb_private::SymbolFile *
CreateInstance(lldb_private::ObjectFile *obj_file);
- //------------------------------------------------------------------
+ static lldb_private::FileSpecList GetSymlinkPaths();
+
// Constructors and Destructors
- //------------------------------------------------------------------
- SymbolFileDWARF(lldb_private::ObjectFile *ofile);
+ SymbolFileDWARF(lldb_private::ObjectFile *ofile,
+ lldb_private::SectionList *dwo_section_list);
~SymbolFileDWARF() override;
@@ -98,9 +93,7 @@ public:
void InitializeObject() override;
- //------------------------------------------------------------------
// Compile Unit function calls
- //------------------------------------------------------------------
uint32_t GetNumCompileUnits() override;
@@ -124,7 +117,7 @@ public:
bool ParseImportedModules(
const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) override;
+ std::vector<lldb_private::SourceModule> &imported_modules) override;
size_t ParseBlocksRecursive(lldb_private::Function &func) override;
@@ -142,11 +135,6 @@ public:
bool assert_not_being_parsed = true,
bool resolve_function_context = false);
- SymbolFileDWARF *GetDWARFForUID(lldb::user_id_t uid);
-
- DWARFDIE
- GetDIEFromUID(lldb::user_id_t uid);
-
lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;
lldb_private::CompilerDeclContext
@@ -169,7 +157,7 @@ public:
lldb_private::SymbolContextList &sc_list) override;
uint32_t
- FindGlobalVariables(const lldb_private::ConstString &name,
+ FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
@@ -179,7 +167,7 @@ public:
lldb_private::VariableList &variables) override;
uint32_t
- FindFunctions(const lldb_private::ConstString &name,
+ FindFunctions(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
lldb::FunctionNameType name_type_mask, bool include_inlines,
bool append, lldb_private::SymbolContextList &sc_list) override;
@@ -193,7 +181,7 @@ public:
std::vector<lldb_private::ConstString> &mangled_names) override;
uint32_t
- FindTypes(const lldb_private::ConstString &name,
+ FindTypes(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
bool append, uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
@@ -212,40 +200,20 @@ public:
GetTypeSystemForLanguage(lldb::LanguageType language) override;
lldb_private::CompilerDeclContext FindNamespace(
- const lldb_private::ConstString &name,
+ lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
void PreloadSymbols() override;
std::recursive_mutex &GetModuleMutex() const override;
- //------------------------------------------------------------------
// PluginInterface protocol
- //------------------------------------------------------------------
lldb_private::ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
- virtual const lldb_private::DWARFDataExtractor &get_debug_abbrev_data();
- virtual const lldb_private::DWARFDataExtractor &get_debug_addr_data();
- const lldb_private::DWARFDataExtractor &get_debug_aranges_data();
- const lldb_private::DWARFDataExtractor &get_debug_frame_data();
- virtual const lldb_private::DWARFDataExtractor &get_debug_info_data();
- const lldb_private::DWARFDataExtractor &get_debug_line_data();
- const lldb_private::DWARFDataExtractor &get_debug_line_str_data();
- const lldb_private::DWARFDataExtractor &get_debug_macro_data();
const lldb_private::DWARFDataExtractor &get_debug_loc_data();
const lldb_private::DWARFDataExtractor &get_debug_loclists_data();
- const lldb_private::DWARFDataExtractor &get_debug_ranges_data();
- const lldb_private::DWARFDataExtractor &get_debug_rnglists_data();
- virtual const lldb_private::DWARFDataExtractor &get_debug_str_data();
- virtual const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data();
- const lldb_private::DWARFDataExtractor &get_debug_types_data();
- const lldb_private::DWARFDataExtractor &get_apple_names_data();
- const lldb_private::DWARFDataExtractor &get_apple_types_data();
- const lldb_private::DWARFDataExtractor &get_apple_namespaces_data();
- const lldb_private::DWARFDataExtractor &get_apple_objc_data();
- const lldb_private::DWARFDataExtractor &get_gnu_debugaltlink();
DWARFDebugAbbrev *DebugAbbrev();
@@ -255,9 +223,8 @@ public:
const DWARFDebugInfo *DebugInfo() const;
- DWARFDebugRangesBase *DebugRanges();
-
- const DWARFDebugRangesBase *DebugRanges() const;
+ DWARFDebugRangesBase *GetDebugRanges();
+ DWARFDebugRangesBase *GetDebugRngLists();
const lldb_private::DWARFDataExtractor &DebugLocData();
@@ -270,8 +237,7 @@ public:
HasForwardDeclForClangType(const lldb_private::CompilerType &compiler_type);
lldb_private::CompileUnit *
- GetCompUnitForDWARFCompUnit(DWARFUnit *dwarf_cu,
- uint32_t cu_idx = UINT32_MAX);
+ GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu);
virtual size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
DIEArray &method_die_offsets);
@@ -282,8 +248,7 @@ public:
static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die);
- virtual lldb::CompUnitSP ParseCompileUnit(DWARFUnit *dwarf_cu,
- uint32_t cu_idx);
+ virtual lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu);
virtual lldb_private::DWARFExpression::LocationListFormat
GetLocationListFormat() const;
@@ -300,6 +265,18 @@ public:
virtual DWARFDIE GetDIE(const DIERef &die_ref);
+ DWARFDIE GetDIE(lldb::user_id_t uid);
+
+ lldb::user_id_t GetUID(const DWARFBaseDIE &die) {
+ return GetUID(die.GetDIERef());
+ }
+
+ lldb::user_id_t GetUID(const llvm::Optional<DIERef> &ref) {
+ return ref ? GetUID(*ref) : LLDB_INVALID_UID;
+ }
+
+ lldb::user_id_t GetUID(DIERef ref);
+
virtual std::unique_ptr<SymbolFileDWARFDwo>
GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu,
const DWARFDebugInfoEntry &cu_die);
@@ -307,7 +284,9 @@ public:
// For regular SymbolFileDWARF instances the method returns nullptr,
// for the instances of the subclass SymbolFileDWARFDwo
// the method returns a pointer to the base compile unit.
- virtual DWARFUnit *GetBaseCompileUnit();
+ virtual DWARFCompileUnit *GetBaseCompileUnit() { return nullptr; }
+
+ virtual llvm::Optional<uint32_t> GetDwoNum() { return llvm::None; }
static bool
DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx,
@@ -320,6 +299,10 @@ public:
void DumpClangAST(lldb_private::Stream &s) override;
+ lldb_private::DWARFContext &GetDWARFContext() { return m_context; }
+
+ lldb_private::FileSpec GetFile(DWARFUnit &unit, size_t file_idx);
+
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
DIEToTypePtr;
@@ -328,7 +311,8 @@ protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
lldb::opaque_compiler_type_t>
DIEToClangType;
- typedef llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> ClangTypeToDIE;
+ typedef llvm::DenseMap<lldb::opaque_compiler_type_t, lldb::user_id_t>
+ ClangTypeToDIE;
struct DWARFDataSegment {
llvm::once_flag m_flag;
@@ -381,7 +365,7 @@ protected:
const DWARFDIE &orig_die,
const lldb::addr_t func_low_pc, bool parse_siblings,
bool parse_children,
- lldb_private::VariableList *cc_variable_list = NULL);
+ lldb_private::VariableList *cc_variable_list = nullptr);
bool ClassOrStructIsVirtual(const DWARFDIE &die);
@@ -393,11 +377,11 @@ protected:
FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
virtual lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
- const DWARFDIE &die, const lldb_private::ConstString &type_name,
+ const DWARFDIE &die, lldb_private::ConstString type_name,
bool must_be_implementation);
lldb_private::Symbol *
- GetObjCClassSymbol(const lldb_private::ConstString &objc_class_name);
+ GetObjCClassSymbol(lldb_private::ConstString objc_class_name);
lldb::TypeSP GetTypeForDIE(const DWARFDIE &die,
bool resolve_function_context = false);
@@ -421,7 +405,7 @@ protected:
bool DIEDeclContextsMatch(const DWARFDIE &die1, const DWARFDIE &die2);
bool ClassContainsSelector(const DWARFDIE &class_die,
- const lldb_private::ConstString &selector);
+ lldb_private::ConstString selector);
bool FixupAddress(lldb_private::Address &addr);
@@ -451,44 +435,35 @@ protected:
return m_forward_decl_clang_type_to_die;
}
+ void BuildCuTranslationTable();
+ llvm::Optional<uint32_t> GetDWARFUnitIndex(uint32_t cu_idx);
+
+ struct DecodedUID {
+ SymbolFileDWARF &dwarf;
+ DIERef ref;
+ };
+ llvm::Optional<DecodedUID> DecodeUID(lldb::user_id_t uid);
+
SymbolFileDWARFDwp *GetDwpSymbolFile();
+ const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu);
+
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap *m_debug_map_symfile;
llvm::once_flag m_dwp_symfile_once_flag;
std::unique_ptr<SymbolFileDWARFDwp> m_dwp_symfile;
- lldb_private::DWARFDataExtractor m_dwarf_data;
+ lldb_private::DWARFContext m_context;
- DWARFDataSegment m_data_debug_abbrev;
- DWARFDataSegment m_data_debug_addr;
- DWARFDataSegment m_data_debug_aranges;
- DWARFDataSegment m_data_debug_frame;
- DWARFDataSegment m_data_debug_info;
- DWARFDataSegment m_data_debug_line;
- DWARFDataSegment m_data_debug_line_str;
- DWARFDataSegment m_data_debug_macro;
DWARFDataSegment m_data_debug_loc;
DWARFDataSegment m_data_debug_loclists;
- DWARFDataSegment m_data_debug_ranges;
- DWARFDataSegment m_data_debug_rnglists;
- DWARFDataSegment m_data_debug_str;
- DWARFDataSegment m_data_debug_str_offsets;
- DWARFDataSegment m_data_debug_types;
- DWARFDataSegment m_data_apple_names;
- DWARFDataSegment m_data_apple_types;
- DWARFDataSegment m_data_apple_namespaces;
- DWARFDataSegment m_data_apple_objc;
- DWARFDataSegment m_data_gnu_debugaltlink;
// The unique pointer items below are generated on demand if and when someone
- // accesses
- // them through a non const version of this class.
+ // accesses them through a non const version of this class.
std::unique_ptr<DWARFDebugAbbrev> m_abbr;
std::unique_ptr<DWARFDebugInfo> m_info;
- std::unique_ptr<DWARFDebugLine> m_line;
- std::unique_ptr<GlobalVariableMap> m_global_aranges_ap;
+ std::unique_ptr<GlobalVariableMap> m_global_aranges_up;
typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP>
DebugMacrosMap;
@@ -499,15 +474,19 @@ protected:
bool m_fetched_external_modules : 1;
lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
- typedef std::shared_ptr<std::set<DIERef>> DIERefSetSP;
- typedef std::unordered_map<std::string, DIERefSetSP> NameToOffsetMap;
+ typedef std::set<lldb::user_id_t> DIERefSet;
+ typedef llvm::StringMap<DIERefSet> NameToOffsetMap;
NameToOffsetMap m_function_scope_qualified_name_map;
std::unique_ptr<DWARFDebugRangesBase> m_ranges;
+ std::unique_ptr<DWARFDebugRangesBase> m_rnglists;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
DIEToTypePtr m_die_to_type;
DIEToVariableSP m_die_to_variable_sp;
DIEToClangType m_forward_decl_die_to_clang_type;
ClangTypeToDIE m_forward_decl_clang_type_to_die;
+ llvm::DenseMap<dw_offset_t, lldb_private::FileSpecList>
+ m_type_unit_support_files;
+ std::vector<uint32_t> m_lldb_cu_to_dwarf_unit;
};
#endif // SymbolFileDWARF_SymbolFileDWARF_h_
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index 2c1e6416a935..8ec64dbaf764 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -1,22 +1,20 @@
//===-- SymbolFileDWARFDebugMap.cpp -----------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "SymbolFileDWARFDebugMap.h"
-
#include "DWARFDebugAranges.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RangeMap.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/FileSystem.h"
+#include "lldb/Utility/RangeMap.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Timer.h"
@@ -36,6 +34,8 @@
#include "LogChannelDWARF.h"
#include "SymbolFileDWARF.h"
+#include <memory>
+
using namespace lldb;
using namespace lldb_private;
@@ -60,13 +60,11 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
return file_range_map;
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
- if (log) {
- ConstString object_name(oso_module->GetObjectName());
+ if (log)
log->Printf(
"%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
static_cast<void *>(this),
oso_module->GetSpecificationDescription().c_str());
- }
std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) {
@@ -177,10 +175,10 @@ public:
SymbolVendor *
GetSymbolVendor(bool can_create = true,
- lldb_private::Stream *feedback_strm = NULL) override {
+ lldb_private::Stream *feedback_strm = nullptr) override {
// Scope for locker
- if (m_symfile_ap.get() || !can_create)
- return m_symfile_ap.get();
+ if (m_symfile_up.get() || !can_create)
+ return m_symfile_up.get();
ModuleSP exe_module_sp(m_exe_module_wp.lock());
if (exe_module_sp) {
@@ -199,7 +197,7 @@ public:
symbol_vendor->GetSymbolFile());
if (!oso_symfile)
- return NULL;
+ return nullptr;
ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
@@ -215,7 +213,7 @@ public:
}
}
}
- return NULL;
+ return nullptr;
}
protected:
@@ -370,12 +368,12 @@ void SymbolFileDWARFDebugMap::InitOSO() {
oso_symbol->GetName().GetCString());
}
} else {
- if (oso_symbol == NULL)
+ if (oso_symbol == nullptr)
m_obj_file->GetModule()->ReportError(
"N_OSO symbol[%u] can't be found, please file a bug and attach "
"the binary listed in this error",
oso_idx);
- else if (so_symbol == NULL)
+ else if (so_symbol == nullptr)
m_obj_file->GetModule()->ReportError(
"N_SO not found for N_OSO symbol[%u], please file a bug and "
"attach the binary listed in this error",
@@ -400,7 +398,7 @@ Module *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) {
const uint32_t cu_count = GetNumCompileUnits();
if (oso_idx < cu_count)
return GetModuleByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
- return NULL;
+ return nullptr;
}
Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
@@ -412,7 +410,7 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
comp_unit_info->oso_sp = pos->second;
} else {
ObjectFile *obj_file = GetObjectFile();
- comp_unit_info->oso_sp.reset(new OSOInfo());
+ comp_unit_info->oso_sp = std::make_shared<OSOInfo>();
m_oso_map[{comp_unit_info->oso_path, comp_unit_info->oso_mod_time}] =
comp_unit_info->oso_sp;
const char *oso_path = comp_unit_info->oso_path.GetCString();
@@ -430,7 +428,7 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
") since this executable was linked, file will be ignored",
oso_file.GetPath().c_str(), llvm::to_string(oso_mod_time).c_str(),
llvm::to_string(comp_unit_info->oso_mod_time).c_str());
- return NULL;
+ return nullptr;
}
} else {
@@ -438,7 +436,7 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
if (!ObjectFile::SplitArchivePathWithObject(oso_path, oso_file,
oso_object, must_exist)) {
- return NULL;
+ return nullptr;
}
}
// Always create a new module for .o files. Why? Because we use the debug
@@ -456,16 +454,15 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
.getArchName()
.str()
.c_str());
- comp_unit_info->oso_sp->module_sp.reset(new DebugMapModule(
+ comp_unit_info->oso_sp->module_sp = std::make_shared<DebugMapModule>(
obj_file->GetModule(), GetCompUnitInfoIndex(comp_unit_info), oso_file,
- oso_arch, oso_object ? &oso_object : NULL, 0,
- oso_object ? comp_unit_info->oso_mod_time
- : llvm::sys::TimePoint<>()));
+ oso_arch, oso_object ? &oso_object : nullptr, 0,
+ oso_object ? comp_unit_info->oso_mod_time : llvm::sys::TimePoint<>());
}
}
if (comp_unit_info->oso_sp)
return comp_unit_info->oso_sp->module_sp.get();
- return NULL;
+ return nullptr;
}
bool SymbolFileDWARFDebugMap::GetFileSpecForSO(uint32_t oso_idx,
@@ -483,7 +480,7 @@ ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) {
Module *oso_module = GetModuleByOSOIndex(oso_idx);
if (oso_module)
return oso_module->GetObjectFile();
- return NULL;
+ return nullptr;
}
SymbolFileDWARF *
@@ -496,7 +493,7 @@ SymbolFileDWARFDebugMap::GetSymbolFile(const CompileUnit &comp_unit) {
CompileUnitInfo *comp_unit_info = GetCompUnitInfo(comp_unit);
if (comp_unit_info)
return GetSymbolFileByCompUnitInfo(comp_unit_info);
- return NULL;
+ return nullptr;
}
ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo(
@@ -504,7 +501,7 @@ ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo(
Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
if (oso_module)
return oso_module->GetObjectFile();
- return NULL;
+ return nullptr;
}
uint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex(
@@ -524,7 +521,7 @@ SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) {
unsigned size = m_compile_unit_infos.size();
if (oso_idx < size)
return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
- return NULL;
+ return nullptr;
}
SymbolFileDWARF *
@@ -532,7 +529,7 @@ SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) {
if (sym_file &&
sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
return (SymbolFileDWARF *)sym_file;
- return NULL;
+ return nullptr;
}
SymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo(
@@ -543,7 +540,7 @@ SymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo(
if (sym_vendor)
return GetSymbolFileAsSymbolFileDWARF(sym_vendor->GetSymbolFile());
}
- return NULL;
+ return nullptr;
}
uint32_t SymbolFileDWARFDebugMap::CalculateAbilities() {
@@ -582,9 +579,10 @@ CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) {
// User zero as the ID to match the compile unit at offset zero in each
// .o file since each .o file can only have one compile unit for now.
lldb::user_id_t cu_id = 0;
- m_compile_unit_infos[cu_idx].compile_unit_sp.reset(
- new CompileUnit(m_obj_file->GetModule(), NULL, so_file_spec, cu_id,
- eLanguageTypeUnknown, eLazyBoolCalculate));
+ m_compile_unit_infos[cu_idx].compile_unit_sp =
+ std::make_shared<CompileUnit>(
+ m_obj_file->GetModule(), nullptr, so_file_spec, cu_id,
+ eLanguageTypeUnknown, eLazyBoolCalculate);
if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
// Let our symbol vendor know about this compile unit
@@ -611,7 +609,7 @@ SymbolFileDWARFDebugMap::GetCompUnitInfo(const CompileUnit &comp_unit) {
if (comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
return &m_compile_unit_infos[i];
}
- return NULL;
+ return nullptr;
}
size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule(
@@ -670,7 +668,7 @@ bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) {
}
bool SymbolFileDWARFDebugMap::ParseImportedModules(
- const SymbolContext &sc, std::vector<ConstString> &imported_modules) {
+ const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
if (oso_dwarf)
return oso_dwarf->ParseImportedModules(sc, imported_modules);
@@ -708,7 +706,7 @@ Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) {
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
if (oso_dwarf)
return oso_dwarf->ResolveTypeUID(type_uid);
- return NULL;
+ return nullptr;
}
llvm::Optional<SymbolFile::ArrayInfo>
@@ -752,7 +750,7 @@ SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
sc.symbol =
symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
- if (sc.symbol != NULL) {
+ if (sc.symbol != nullptr) {
resolved_flags |= eSymbolContextSymbol;
uint32_t oso_idx = 0;
@@ -810,7 +808,7 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
}
uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
const std::vector<uint32_t>
&indexes, // Indexes into the symbol table that match "name"
uint32_t max_matches, VariableList &variables) {
@@ -834,7 +832,7 @@ uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
}
uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
// Remember how many variables are in the list before we search.
@@ -932,7 +930,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo *
SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex(
uint32_t symbol_idx, uint32_t *oso_idx_ptr) {
const uint32_t oso_index_count = m_compile_unit_infos.size();
- CompileUnitInfo *comp_unit_info = NULL;
+ CompileUnitInfo *comp_unit_info = nullptr;
if (oso_index_count) {
comp_unit_info = (CompileUnitInfo *)bsearch(
&symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
@@ -941,7 +939,7 @@ SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex(
}
if (oso_idx_ptr) {
- if (comp_unit_info != NULL)
+ if (comp_unit_info != nullptr)
*oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
else
*oso_idx_ptr = UINT32_MAX;
@@ -953,7 +951,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo *
SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID(
user_id_t symbol_id, uint32_t *oso_idx_ptr) {
const uint32_t oso_index_count = m_compile_unit_infos.size();
- CompileUnitInfo *comp_unit_info = NULL;
+ CompileUnitInfo *comp_unit_info = nullptr;
if (oso_index_count) {
comp_unit_info = (CompileUnitInfo *)::bsearch(
&symbol_id, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
@@ -962,7 +960,7 @@ SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID(
}
if (oso_idx_ptr) {
- if (comp_unit_info != NULL)
+ if (comp_unit_info != nullptr)
*oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
else
*oso_idx_ptr = UINT32_MAX;
@@ -996,7 +994,7 @@ static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
}
uint32_t SymbolFileDWARFDebugMap::FindFunctions(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
FunctionNameType name_type_mask, bool include_inlines, bool append,
SymbolContextList &sc_list) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
@@ -1060,7 +1058,7 @@ size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
type_mask);
uint32_t initial_size = type_list.GetSize();
- SymbolFileDWARF *oso_dwarf = NULL;
+ SymbolFileDWARF *oso_dwarf = nullptr;
if (sc_scope) {
SymbolContext sc;
sc_scope->CalculateSymbolContext(&sc);
@@ -1105,7 +1103,7 @@ bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type(
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
if (skip_dwarf_oso != oso_dwarf &&
- oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) {
+ oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(nullptr)) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
return true;
}
@@ -1116,7 +1114,7 @@ bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type(
}
TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
- const DWARFDIE &die, const ConstString &type_name,
+ const DWARFDIE &die, ConstString type_name,
bool must_be_implementation) {
// If we have a debug map, we will have an Objective-C symbol whose name is
// the type name and whose type is eSymbolTypeObjCClass. If we can find that
@@ -1124,7 +1122,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
// contain the implementation definition since it will be scoped inside the
// N_SO and we can then locate the SymbolFileDWARF that corresponds to that
// N_SO.
- SymbolFileDWARF *oso_dwarf = NULL;
+ SymbolFileDWARF *oso_dwarf = nullptr;
TypeSP type_sp;
ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
if (module_objfile) {
@@ -1145,7 +1143,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
if (source_file_symbol_idx != UINT32_MAX) {
CompileUnitInfo *compile_unit_info =
GetCompileUnitInfoForSymbolWithIndex(source_file_symbol_idx,
- NULL);
+ nullptr);
if (compile_unit_info) {
oso_dwarf = GetSymbolFileByCompUnitInfo(compile_unit_info);
if (oso_dwarf) {
@@ -1180,7 +1178,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
}
uint32_t SymbolFileDWARFDebugMap::FindTypes(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
bool append, uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
@@ -1212,7 +1210,7 @@ uint32_t SymbolFileDWARFDebugMap::FindTypes(
//}
CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
- const lldb_private::ConstString &name,
+ lldb_private::ConstString name,
const CompilerDeclContext *parent_decl_ctx) {
CompilerDeclContext matching_namespace;
@@ -1232,9 +1230,7 @@ void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) {
});
}
-//------------------------------------------------------------------
// PluginInterface protocol
-//------------------------------------------------------------------
lldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginName() {
return GetPluginNameStatic();
}
@@ -1272,7 +1268,7 @@ SymbolFileDWARFDebugMap::GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf) {
}
}
}
- return NULL;
+ return nullptr;
}
void SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf,
@@ -1418,7 +1414,7 @@ LineTable *SymbolFileDWARFDebugMap::LinkOSOLineTable(SymbolFileDWARF *oso_dwarf,
CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_dwarf);
if (cu_info)
return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
- return NULL;
+ return nullptr;
}
size_t
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index 176eadeeca71..afc6142e8231 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -1,23 +1,21 @@
//===-- SymbolFileDWARFDebugMap.h ------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
#define SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Utility/RangeMap.h"
+#include "llvm/Support/Chrono.h"
#include <bitset>
#include <map>
#include <vector>
-#include "lldb/Core/RangeMap.h"
-#include "lldb/Symbol/SymbolFile.h"
-#include "llvm/Support/Chrono.h"
-
#include "UniqueDWARFASTType.h"
class SymbolFileDWARF;
@@ -26,9 +24,7 @@ class DWARFDeclContext;
class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile {
public:
- //------------------------------------------------------------------
// Static Functions
- //------------------------------------------------------------------
static void Initialize();
static void Terminate();
@@ -40,18 +36,14 @@ public:
static lldb_private::SymbolFile *
CreateInstance(lldb_private::ObjectFile *obj_file);
- //------------------------------------------------------------------
// Constructors and Destructors
- //------------------------------------------------------------------
SymbolFileDWARFDebugMap(lldb_private::ObjectFile *ofile);
~SymbolFileDWARFDebugMap() override;
uint32_t CalculateAbilities() override;
void InitializeObject() override;
- //------------------------------------------------------------------
// Compile Unit function calls
- //------------------------------------------------------------------
uint32_t GetNumCompileUnits() override;
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
@@ -73,7 +65,7 @@ public:
bool ParseImportedModules(
const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) override;
+ std::vector<lldb_private::SourceModule> &imported_modules) override;
size_t ParseBlocksRecursive(lldb_private::Function &func) override;
size_t
ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
@@ -100,7 +92,7 @@ public:
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
uint32_t
- FindGlobalVariables(const lldb_private::ConstString &name,
+ FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
@@ -108,7 +100,7 @@ public:
uint32_t max_matches,
lldb_private::VariableList &variables) override;
uint32_t
- FindFunctions(const lldb_private::ConstString &name,
+ FindFunctions(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
lldb::FunctionNameType name_type_mask, bool include_inlines,
bool append, lldb_private::SymbolContextList &sc_list) override;
@@ -116,13 +108,13 @@ public:
bool include_inlines, bool append,
lldb_private::SymbolContextList &sc_list) override;
uint32_t
- FindTypes(const lldb_private::ConstString &name,
+ FindTypes(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
bool append, uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
lldb_private::CompilerDeclContext FindNamespace(
- const lldb_private::ConstString &name,
+ lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
lldb::TypeClass type_mask,
@@ -132,9 +124,7 @@ public:
void DumpClangAST(lldb_private::Stream &s) override;
- //------------------------------------------------------------------
// PluginInterface protocol
- //------------------------------------------------------------------
lldb_private::ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
@@ -143,9 +133,8 @@ protected:
enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
friend class DebugMapModule;
- friend struct DIERef;
friend class DWARFASTParserClang;
- friend class DWARFUnit;
+ friend class DWARFCompileUnit;
friend class SymbolFileDWARF;
struct OSOInfo {
lldb::ModuleSP module_sp;
@@ -159,9 +148,7 @@ protected:
lldb::addr_t>
FileRangeMap;
- //------------------------------------------------------------------
// Class specific types
- //------------------------------------------------------------------
struct CompileUnitInfo {
lldb_private::FileSpec so_file;
lldb_private::ConstString oso_path;
@@ -184,9 +171,7 @@ protected:
const FileRangeMap &GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
};
- //------------------------------------------------------------------
// Protected Member Functions
- //------------------------------------------------------------------
void InitOSO();
static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
@@ -248,7 +233,7 @@ protected:
const CompileUnitInfo *comp_unit_info);
uint32_t PrivateFindGlobalVariables(
- const lldb_private::ConstString &name,
+ lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
const std::vector<uint32_t> &name_symbol_indexes, uint32_t max_matches,
lldb_private::VariableList &variables);
@@ -266,16 +251,14 @@ protected:
bool Supports_DW_AT_APPLE_objc_complete_type(SymbolFileDWARF *skip_dwarf_oso);
lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
- const DWARFDIE &die, const lldb_private::ConstString &type_name,
+ const DWARFDIE &die, lldb_private::ConstString type_name,
bool must_be_implementation);
UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() {
return m_unique_ast_type_map;
}
- //------------------------------------------------------------------
// OSOEntry
- //------------------------------------------------------------------
class OSOEntry {
public:
OSOEntry()
@@ -304,9 +287,7 @@ protected:
typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry>
DebugMap;
- //------------------------------------------------------------------
// Member Variables
- //------------------------------------------------------------------
std::bitset<kNumFlags> m_flags;
std::vector<CompileUnitInfo> m_compile_unit_infos;
std::vector<uint32_t> m_func_indexes; // Sorted by address
@@ -318,68 +299,58 @@ protected:
lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
DebugMap m_debug_map;
- //------------------------------------------------------------------
// When an object file from the debug map gets parsed in
// SymbolFileDWARF, it needs to tell the debug map about the object
// files addresses by calling this function once for each N_FUN,
// N_GSYM and N_STSYM and after all entries in the debug map have
// been matched up, FinalizeOSOFileRanges() should be called.
- //------------------------------------------------------------------
bool AddOSOFileRange(CompileUnitInfo *cu_info, lldb::addr_t exe_file_addr,
lldb::addr_t exe_byte_size, lldb::addr_t oso_file_addr,
lldb::addr_t oso_byte_size);
- //------------------------------------------------------------------
// Called after calling AddOSOFileRange() for each object file debug
// map entry to finalize the info for the unlinked compile unit.
- //------------------------------------------------------------------
void FinalizeOSOFileRanges(CompileUnitInfo *cu_info);
- //------------------------------------------------------------------
/// Convert \a addr from a .o file address, to an executable address.
///
- /// @param[in] addr
+ /// \param[in] addr
/// A section offset address from a .o file
///
- /// @return
+ /// \return
/// Returns true if \a addr was converted to be an executable
/// section/offset address, false otherwise.
- //------------------------------------------------------------------
bool LinkOSOAddress(lldb_private::Address &addr);
- //------------------------------------------------------------------
/// Convert a .o file "file address" to an executable "file address".
///
- /// @param[in] oso_symfile
+ /// \param[in] oso_symfile
/// The DWARF symbol file that contains \a oso_file_addr
///
- /// @param[in] oso_file_addr
+ /// \param[in] oso_file_addr
/// A .o file "file address" to convert.
///
- /// @return
+ /// \return
/// LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the
/// linked executable, otherwise a valid "file address" from the
/// linked executable that contains the debug map.
- //------------------------------------------------------------------
lldb::addr_t LinkOSOFileAddress(SymbolFileDWARF *oso_symfile,
lldb::addr_t oso_file_addr);
- //------------------------------------------------------------------
/// Given a line table full of lines with "file addresses" that are
/// for a .o file represented by \a oso_symfile, link a new line table
/// and return it.
///
- /// @param[in] oso_symfile
+ /// \param[in] oso_symfile
/// The DWARF symbol file that produced the \a line_table
///
- /// @param[in] addr
+ /// \param[in] addr
/// A section offset address from a .o file
///
- /// @return
+ /// \return
/// Returns a valid line table full of linked addresses, or NULL
/// if none of the line table addresses exist in the main
/// executable.
- //------------------------------------------------------------------
lldb_private::LineTable *
LinkOSOLineTable(SymbolFileDWARF *oso_symfile,
lldb_private::LineTable *line_table);
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index 7881448535b8..c5b54b65ea29 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -1,9 +1,8 @@
//===-- SymbolFileDWARFDwo.cpp ----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -13,18 +12,21 @@
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "llvm/Support/Casting.h"
-#include "DWARFUnit.h"
+#include "DWARFCompileUnit.h"
#include "DWARFDebugInfo.h"
+#include "DWARFUnit.h"
using namespace lldb;
using namespace lldb_private;
SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile,
- DWARFUnit *dwarf_cu)
- : SymbolFileDWARF(objfile.get()), m_obj_file_sp(objfile),
- m_base_dwarf_cu(dwarf_cu) {
- SetID(((lldb::user_id_t)dwarf_cu->GetOffset()) << 32);
+ DWARFCompileUnit &dwarf_cu)
+ : SymbolFileDWARF(objfile.get(), objfile->GetSectionList(
+ /*update_module_section_list*/ false)),
+ m_obj_file_sp(objfile), m_base_dwarf_cu(dwarf_cu) {
+ SetID(((lldb::user_id_t)dwarf_cu.GetID()) << 32);
}
void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type,
@@ -34,12 +36,6 @@ void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type,
if (section_list) {
SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
if (section_sp) {
- // See if we memory mapped the DWARF segment?
- if (m_dwarf_data.GetByteSize()) {
- data.SetData(m_dwarf_data, section_sp->GetOffset(),
- section_sp->GetFileSize());
- return;
- }
if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0)
return;
@@ -52,20 +48,41 @@ void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type,
}
lldb::CompUnitSP
-SymbolFileDWARFDwo::ParseCompileUnit(DWARFUnit *dwarf_cu,
- uint32_t cu_idx) {
- assert(GetCompileUnit() == dwarf_cu && "SymbolFileDWARFDwo::ParseCompileUnit "
- "called with incompatible compile "
- "unit");
- return GetBaseSymbolFile()->ParseCompileUnit(m_base_dwarf_cu, UINT32_MAX);
-}
-
-DWARFUnit *SymbolFileDWARFDwo::GetCompileUnit() {
- // Only dwo files with 1 compile unit is supported
- if (GetNumCompileUnits() == 1)
- return DebugInfo()->GetCompileUnitAtIndex(0);
- else
+SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
+ assert(GetCompileUnit() == &dwarf_cu &&
+ "SymbolFileDWARFDwo::ParseCompileUnit called with incompatible "
+ "compile unit");
+ return GetBaseSymbolFile().ParseCompileUnit(m_base_dwarf_cu);
+}
+
+DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() {
+ if (!m_cu)
+ m_cu = ComputeCompileUnit();
+ return m_cu;
+}
+
+DWARFCompileUnit *SymbolFileDWARFDwo::ComputeCompileUnit() {
+ DWARFDebugInfo *debug_info = DebugInfo();
+ if (!debug_info)
return nullptr;
+
+ // Right now we only support dwo files with one compile unit. If we don't have
+ // type units, we can just check for the unit count.
+ if (!debug_info->ContainsTypeUnits() && debug_info->GetNumUnits() == 1)
+ return llvm::cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(0));
+
+ // Otherwise, we have to run through all units, and find the compile unit that
+ // way.
+ DWARFCompileUnit *cu = nullptr;
+ for (size_t i = 0; i < debug_info->GetNumUnits(); ++i) {
+ if (auto *candidate =
+ llvm::dyn_cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(i))) {
+ if (cu)
+ return nullptr; // More that one CU found.
+ cu = candidate;
+ }
+ }
+ return cu;
}
DWARFUnit *
@@ -74,83 +91,48 @@ SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
}
SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() {
- return GetBaseSymbolFile()->GetDIEToType();
+ return GetBaseSymbolFile().GetDIEToType();
}
SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() {
- return GetBaseSymbolFile()->GetDIEToVariable();
+ return GetBaseSymbolFile().GetDIEToVariable();
}
SymbolFileDWARF::DIEToClangType &
SymbolFileDWARFDwo::GetForwardDeclDieToClangType() {
- return GetBaseSymbolFile()->GetForwardDeclDieToClangType();
+ return GetBaseSymbolFile().GetForwardDeclDieToClangType();
}
SymbolFileDWARF::ClangTypeToDIE &
SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() {
- return GetBaseSymbolFile()->GetForwardDeclClangTypeToDie();
+ return GetBaseSymbolFile().GetForwardDeclClangTypeToDie();
}
size_t SymbolFileDWARFDwo::GetObjCMethodDIEOffsets(
lldb_private::ConstString class_name, DIEArray &method_die_offsets) {
- return GetBaseSymbolFile()->GetObjCMethodDIEOffsets(
- class_name, method_die_offsets);
+ return GetBaseSymbolFile().GetObjCMethodDIEOffsets(class_name,
+ method_die_offsets);
}
UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() {
- return GetBaseSymbolFile()->GetUniqueDWARFASTTypeMap();
+ return GetBaseSymbolFile().GetUniqueDWARFASTTypeMap();
}
lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext(
const DWARFDeclContext &die_decl_ctx) {
- return GetBaseSymbolFile()->FindDefinitionTypeForDWARFDeclContext(
+ return GetBaseSymbolFile().FindDefinitionTypeForDWARFDeclContext(
die_decl_ctx);
}
lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE(
- const DWARFDIE &die, const lldb_private::ConstString &type_name,
+ const DWARFDIE &die, lldb_private::ConstString type_name,
bool must_be_implementation) {
- return GetBaseSymbolFile()->FindCompleteObjCDefinitionTypeForDIE(
+ return GetBaseSymbolFile().FindCompleteObjCDefinitionTypeForDIE(
die, type_name, must_be_implementation);
}
-DWARFUnit *SymbolFileDWARFDwo::GetBaseCompileUnit() {
- return m_base_dwarf_cu;
-}
-
-const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_abbrev_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugAbbrevDwo,
- m_data_debug_abbrev);
-}
-
-const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_addr_data() {
- // For single file split dwarf case (when we have .dwo sections in a .o),
- // we do not want to use the .debug_addr section from .o file,
- // but want to get one from the final executable.
- // For regular split debug case, .dwo file does not contain the
- // .debug_addr, so we would always fall back to such lookup anyways.
- llvm::call_once(m_data_debug_addr.m_flag, [this] {
- SymbolFileDWARF::LoadSectionData(eSectionTypeDWARFDebugAddr,
- std::ref(m_data_debug_addr.m_data));
- });
- return m_data_debug_addr.m_data;
-}
-
-const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_info_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugInfoDwo, m_data_debug_info);
-}
-
-const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_str_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugStrDwo, m_data_debug_str);
-}
-
-const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_str_offsets_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugStrOffsetsDwo,
- m_data_debug_str_offsets);
-}
-
-SymbolFileDWARF *SymbolFileDWARFDwo::GetBaseSymbolFile() {
- return m_base_dwarf_cu->GetSymbolFileDWARF();
+SymbolFileDWARF &SymbolFileDWARFDwo::GetBaseSymbolFile() {
+ return m_base_dwarf_cu.GetSymbolFileDWARF();
}
DWARFExpression::LocationListFormat
@@ -160,11 +142,12 @@ SymbolFileDWARFDwo::GetLocationListFormat() const {
TypeSystem *
SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
- return GetBaseSymbolFile()->GetTypeSystemForLanguage(language);
+ return GetBaseSymbolFile().GetTypeSystemForLanguage(language);
}
DWARFDIE
SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) {
- lldbassert(m_base_dwarf_cu->GetOffset() == die_ref.cu_offset);
- return DebugInfo()->GetDIEForDIEOffset(die_ref.die_offset);
+ if (*die_ref.dwo_num() == GetDwoNum())
+ return DebugInfo()->GetDIE(die_ref);
+ return GetBaseSymbolFile().GetDIE(die_ref);
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index b9ed37547aca..9b2f3bb84c4f 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -1,9 +1,8 @@
//===-- SymbolFileDWARFDwo.h ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -14,14 +13,13 @@
class SymbolFileDWARFDwo : public SymbolFileDWARF {
public:
- SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFUnit *dwarf_cu);
+ SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit &dwarf_cu);
~SymbolFileDWARFDwo() override = default;
- lldb::CompUnitSP ParseCompileUnit(DWARFUnit *dwarf_cu,
- uint32_t cu_idx) override;
+ lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu) override;
- DWARFUnit *GetCompileUnit();
+ DWARFCompileUnit *GetCompileUnit();
DWARFUnit *
GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override;
@@ -44,13 +42,9 @@ public:
return nullptr;
}
- DWARFUnit *GetBaseCompileUnit() override;
+ DWARFCompileUnit *GetBaseCompileUnit() override { return &m_base_dwarf_cu; }
- const lldb_private::DWARFDataExtractor &get_debug_abbrev_data() override;
- const lldb_private::DWARFDataExtractor &get_debug_addr_data() override;
- const lldb_private::DWARFDataExtractor &get_debug_info_data() override;
- const lldb_private::DWARFDataExtractor &get_debug_str_data() override;
- const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data() override;
+ llvm::Optional<uint32_t> GetDwoNum() override { return GetID() >> 32; }
protected:
void LoadSectionData(lldb::SectionType sect_type,
@@ -70,13 +64,16 @@ protected:
const DWARFDeclContext &die_decl_ctx) override;
lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
- const DWARFDIE &die, const lldb_private::ConstString &type_name,
+ const DWARFDIE &die, lldb_private::ConstString type_name,
bool must_be_implementation) override;
- SymbolFileDWARF *GetBaseSymbolFile();
+ SymbolFileDWARF &GetBaseSymbolFile();
+
+ DWARFCompileUnit *ComputeCompileUnit();
lldb::ObjectFileSP m_obj_file_sp;
- DWARFUnit *m_base_dwarf_cu;
+ DWARFCompileUnit &m_base_dwarf_cu;
+ DWARFCompileUnit *m_cu = nullptr;
};
#endif // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
index 403c10fe65ea..efea192b17ce 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
@@ -1,9 +1,8 @@
//===-- SymbolFileDWARFDwoDwp.cpp -------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -22,7 +21,7 @@ using namespace lldb_private;
SymbolFileDWARFDwoDwp::SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
ObjectFileSP objfile,
- DWARFUnit *dwarf_cu,
+ DWARFCompileUnit &dwarf_cu,
uint64_t dwo_id)
: SymbolFileDWARFDwo(objfile, dwarf_cu), m_dwp_symfile(dwp_symfile),
m_dwo_id(dwo_id) {}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
index 905ba0a5c7b8..2105e1a8f6cb 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
@@ -1,9 +1,8 @@
//===-- SymbolFileDWARFDwoDwp.h ---------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -16,7 +15,7 @@
class SymbolFileDWARFDwoDwp : public SymbolFileDWARFDwo {
public:
SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
- lldb::ObjectFileSP objfile, DWARFUnit *dwarf_cu,
+ lldb::ObjectFileSP objfile, DWARFCompileUnit &dwarf_cu,
uint64_t dwo_id);
protected:
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
index 73226dfc130f..08e6e1c8c2f3 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
@@ -1,9 +1,8 @@
//===-- SymbolFileDWARFDwp.cpp ----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -82,7 +81,7 @@ SymbolFileDWARFDwp::SymbolFileDWARFDwp(lldb::ModuleSP module_sp,
{}
std::unique_ptr<SymbolFileDWARFDwo>
-SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFUnit *dwarf_cu,
+SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu,
uint64_t dwo_id) {
return std::unique_ptr<SymbolFileDWARFDwo>(
new SymbolFileDWARFDwoDwp(this, m_obj_file, dwarf_cu, dwo_id));
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
index 87f4d9402335..ef06b9dca8bb 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
@@ -1,9 +1,8 @@
//===-- SymbolFileDWARFDwp.h ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -25,7 +24,7 @@ public:
Create(lldb::ModuleSP module_sp, const lldb_private::FileSpec &file_spec);
std::unique_ptr<SymbolFileDWARFDwo>
- GetSymbolFileForDwoId(DWARFUnit *dwarf_cu, uint64_t dwo_id);
+ GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu, uint64_t dwo_id);
bool LoadSectionData(uint64_t dwo_id, lldb::SectionType sect_type,
lldb_private::DWARFDataExtractor &data);
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index dd912aecf0d8..8da7e2226266 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -1,9 +1,8 @@
//===-- UniqueDWARFASTType.cpp ----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -40,12 +39,12 @@ bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
case DW_TAG_namespace: {
const char *parent_arg_die_name = parent_arg_die.GetName();
if (parent_arg_die_name ==
- NULL) // Anonymous (i.e. no-name) struct
+ nullptr) // Anonymous (i.e. no-name) struct
{
match = false;
} else {
const char *parent_pos_die_name = parent_pos_die.GetName();
- if (parent_pos_die_name == NULL ||
+ if (parent_pos_die_name == nullptr ||
((parent_arg_die_name != parent_pos_die_name) &&
strcmp(parent_arg_die_name, parent_pos_die_name)))
match = false;
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
index 1e6b164e9457..1269dbac7126 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
@@ -1,9 +1,8 @@
//===-- UniqueDWARFASTType.h ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -19,9 +18,7 @@
class UniqueDWARFASTType {
public:
- //------------------------------------------------------------------
// Constructors and Destructors
- //------------------------------------------------------------------
UniqueDWARFASTType()
: m_type_sp(), m_die(), m_declaration(),
m_byte_size(
@@ -81,12 +78,12 @@ public:
~UniqueDWARFASTTypeMap() {}
- void Insert(const lldb_private::ConstString &name,
+ void Insert(lldb_private::ConstString name,
const UniqueDWARFASTType &entry) {
m_collection[name.GetCString()].Append(entry);
}
- bool Find(const lldb_private::ConstString &name, const DWARFDIE &die,
+ bool Find(lldb_private::ConstString name, const DWARFDIE &die,
const lldb_private::Declaration &decl, const int32_t byte_size,
UniqueDWARFASTType &entry) const {
const char *unique_name_cstr = name.GetCString();
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp
new file mode 100644
index 000000000000..3834165c71c0
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp
@@ -0,0 +1,457 @@
+//===-- CodeViewRegisterMapping.cpp -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeViewRegisterMapping.h"
+
+#include "lldb/lldb-defines.h"
+
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+
+using namespace lldb_private;
+
+static const uint32_t g_code_view_to_lldb_registers_x86[] = {
+ LLDB_INVALID_REGNUM, // NONE
+ lldb_al_i386, // AL
+ lldb_cl_i386, // CL
+ lldb_dl_i386, // DL
+ lldb_bl_i386, // BL
+ lldb_ah_i386, // AH
+ lldb_ch_i386, // CH
+ lldb_dh_i386, // DH
+ lldb_bh_i386, // BH
+ lldb_ax_i386, // AX
+ lldb_cx_i386, // CX
+ lldb_dx_i386, // DX
+ lldb_bx_i386, // BX
+ lldb_sp_i386, // SP
+ lldb_bp_i386, // BP
+ lldb_si_i386, // SI
+ lldb_di_i386, // DI
+ lldb_eax_i386, // EAX
+ lldb_ecx_i386, // ECX
+ lldb_edx_i386, // EDX
+ lldb_ebx_i386, // EBX
+ lldb_esp_i386, // ESP
+ lldb_ebp_i386, // EBP
+ lldb_esi_i386, // ESI
+ lldb_edi_i386, // EDI
+ lldb_es_i386, // ES
+ lldb_cs_i386, // CS
+ lldb_ss_i386, // SS
+ lldb_ds_i386, // DS
+ lldb_fs_i386, // FS
+ lldb_gs_i386, // GS
+ LLDB_INVALID_REGNUM, // IP
+ LLDB_INVALID_REGNUM, // FLAGS
+ lldb_eip_i386, // EIP
+ lldb_eflags_i386, // EFLAGS
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // TEMP
+ LLDB_INVALID_REGNUM, // TEMPH
+ LLDB_INVALID_REGNUM, // QUOTE
+ LLDB_INVALID_REGNUM, // PCDR3
+ LLDB_INVALID_REGNUM, // PCDR4
+ LLDB_INVALID_REGNUM, // PCDR5
+ LLDB_INVALID_REGNUM, // PCDR6
+ LLDB_INVALID_REGNUM, // PCDR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // CR0
+ LLDB_INVALID_REGNUM, // CR1
+ LLDB_INVALID_REGNUM, // CR2
+ LLDB_INVALID_REGNUM, // CR3
+ LLDB_INVALID_REGNUM, // CR4
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_dr0_i386, // DR0
+ lldb_dr1_i386, // DR1
+ lldb_dr2_i386, // DR2
+ lldb_dr3_i386, // DR3
+ lldb_dr4_i386, // DR4
+ lldb_dr5_i386, // DR5
+ lldb_dr6_i386, // DR6
+ lldb_dr7_i386, // DR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // GDTR
+ LLDB_INVALID_REGNUM, // GDTL
+ LLDB_INVALID_REGNUM, // IDTR
+ LLDB_INVALID_REGNUM, // IDTL
+ LLDB_INVALID_REGNUM, // LDTR
+ LLDB_INVALID_REGNUM, // TR
+ LLDB_INVALID_REGNUM, // PSEUDO1
+ LLDB_INVALID_REGNUM, // PSEUDO2
+ LLDB_INVALID_REGNUM, // PSEUDO3
+ LLDB_INVALID_REGNUM, // PSEUDO4
+ LLDB_INVALID_REGNUM, // PSEUDO5
+ LLDB_INVALID_REGNUM, // PSEUDO6
+ LLDB_INVALID_REGNUM, // PSEUDO7
+ LLDB_INVALID_REGNUM, // PSEUDO8
+ LLDB_INVALID_REGNUM, // PSEUDO9
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_st0_i386, // ST0
+ lldb_st1_i386, // ST1
+ lldb_st2_i386, // ST2
+ lldb_st3_i386, // ST3
+ lldb_st4_i386, // ST4
+ lldb_st5_i386, // ST5
+ lldb_st6_i386, // ST6
+ lldb_st7_i386, // ST7
+ LLDB_INVALID_REGNUM, // CTRL
+ LLDB_INVALID_REGNUM, // STAT
+ LLDB_INVALID_REGNUM, // TAG
+ LLDB_INVALID_REGNUM, // FPIP
+ LLDB_INVALID_REGNUM, // FPCS
+ LLDB_INVALID_REGNUM, // FPDO
+ LLDB_INVALID_REGNUM, // FPDS
+ LLDB_INVALID_REGNUM, // ISEM
+ LLDB_INVALID_REGNUM, // FPEIP
+ LLDB_INVALID_REGNUM, // FPEDO
+ lldb_mm0_i386, // MM0
+ lldb_mm1_i386, // MM1
+ lldb_mm2_i386, // MM2
+ lldb_mm3_i386, // MM3
+ lldb_mm4_i386, // MM4
+ lldb_mm5_i386, // MM5
+ lldb_mm6_i386, // MM6
+ lldb_mm7_i386, // MM7
+ lldb_xmm0_i386, // XMM0
+ lldb_xmm1_i386, // XMM1
+ lldb_xmm2_i386, // XMM2
+ lldb_xmm3_i386, // XMM3
+ lldb_xmm4_i386, // XMM4
+ lldb_xmm5_i386, // XMM5
+ lldb_xmm6_i386, // XMM6
+ lldb_xmm7_i386 // XMM7
+};
+
+static const uint32_t g_code_view_to_lldb_registers_x86_64[] = {
+ LLDB_INVALID_REGNUM, // NONE
+ lldb_al_x86_64, // AL
+ lldb_cl_x86_64, // CL
+ lldb_dl_x86_64, // DL
+ lldb_bl_x86_64, // BL
+ lldb_ah_x86_64, // AH
+ lldb_ch_x86_64, // CH
+ lldb_dh_x86_64, // DH
+ lldb_bh_x86_64, // BH
+ lldb_ax_x86_64, // AX
+ lldb_cx_x86_64, // CX
+ lldb_dx_x86_64, // DX
+ lldb_bx_x86_64, // BX
+ lldb_sp_x86_64, // SP
+ lldb_bp_x86_64, // BP
+ lldb_si_x86_64, // SI
+ lldb_di_x86_64, // DI
+ lldb_eax_x86_64, // EAX
+ lldb_ecx_x86_64, // ECX
+ lldb_edx_x86_64, // EDX
+ lldb_ebx_x86_64, // EBX
+ lldb_esp_x86_64, // ESP
+ lldb_ebp_x86_64, // EBP
+ lldb_esi_x86_64, // ESI
+ lldb_edi_x86_64, // EDI
+ lldb_es_x86_64, // ES
+ lldb_cs_x86_64, // CS
+ lldb_ss_x86_64, // SS
+ lldb_ds_x86_64, // DS
+ lldb_fs_x86_64, // FS
+ lldb_gs_x86_64, // GS
+ LLDB_INVALID_REGNUM, // IP
+ LLDB_INVALID_REGNUM, // FLAGS
+ LLDB_INVALID_REGNUM, // EIP
+ LLDB_INVALID_REGNUM, // EFLAGS
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // TEMP
+ LLDB_INVALID_REGNUM, // TEMPH
+ LLDB_INVALID_REGNUM, // QUOTE
+ LLDB_INVALID_REGNUM, // PCDR3
+ LLDB_INVALID_REGNUM, // PCDR4
+ LLDB_INVALID_REGNUM, // PCDR5
+ LLDB_INVALID_REGNUM, // PCDR6
+ LLDB_INVALID_REGNUM, // PCDR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // CR0
+ LLDB_INVALID_REGNUM, // CR1
+ LLDB_INVALID_REGNUM, // CR2
+ LLDB_INVALID_REGNUM, // CR3
+ LLDB_INVALID_REGNUM, // CR4
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_dr0_x86_64, // DR0
+ lldb_dr1_x86_64, // DR1
+ lldb_dr2_x86_64, // DR2
+ lldb_dr3_x86_64, // DR3
+ lldb_dr4_x86_64, // DR4
+ lldb_dr5_x86_64, // DR5
+ lldb_dr6_x86_64, // DR6
+ lldb_dr7_x86_64, // DR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // GDTR
+ LLDB_INVALID_REGNUM, // GDTL
+ LLDB_INVALID_REGNUM, // IDTR
+ LLDB_INVALID_REGNUM, // IDTL
+ LLDB_INVALID_REGNUM, // LDTR
+ LLDB_INVALID_REGNUM, // TR
+ LLDB_INVALID_REGNUM, // PSEUDO1
+ LLDB_INVALID_REGNUM, // PSEUDO2
+ LLDB_INVALID_REGNUM, // PSEUDO3
+ LLDB_INVALID_REGNUM, // PSEUDO4
+ LLDB_INVALID_REGNUM, // PSEUDO5
+ LLDB_INVALID_REGNUM, // PSEUDO6
+ LLDB_INVALID_REGNUM, // PSEUDO7
+ LLDB_INVALID_REGNUM, // PSEUDO8
+ LLDB_INVALID_REGNUM, // PSEUDO9
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_st0_x86_64, // ST0
+ lldb_st1_x86_64, // ST1
+ lldb_st2_x86_64, // ST2
+ lldb_st3_x86_64, // ST3
+ lldb_st4_x86_64, // ST4
+ lldb_st5_x86_64, // ST5
+ lldb_st6_x86_64, // ST6
+ lldb_st7_x86_64, // ST7
+ LLDB_INVALID_REGNUM, // CTRL
+ LLDB_INVALID_REGNUM, // STAT
+ LLDB_INVALID_REGNUM, // TAG
+ LLDB_INVALID_REGNUM, // FPIP
+ LLDB_INVALID_REGNUM, // FPCS
+ LLDB_INVALID_REGNUM, // FPDO
+ LLDB_INVALID_REGNUM, // FPDS
+ LLDB_INVALID_REGNUM, // ISEM
+ LLDB_INVALID_REGNUM, // FPEIP
+ LLDB_INVALID_REGNUM, // FPEDO
+ lldb_mm0_x86_64, // MM0
+ lldb_mm1_x86_64, // MM1
+ lldb_mm2_x86_64, // MM2
+ lldb_mm3_x86_64, // MM3
+ lldb_mm4_x86_64, // MM4
+ lldb_mm5_x86_64, // MM5
+ lldb_mm6_x86_64, // MM6
+ lldb_mm7_x86_64, // MM7
+ lldb_xmm0_x86_64, // XMM0
+ lldb_xmm1_x86_64, // XMM1
+ lldb_xmm2_x86_64, // XMM2
+ lldb_xmm3_x86_64, // XMM3
+ lldb_xmm4_x86_64, // XMM4
+ lldb_xmm5_x86_64, // XMM5
+ lldb_xmm6_x86_64, // XMM6
+ lldb_xmm7_x86_64, // XMM7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM,
+ lldb_mxcsr_x86_64, // MXCSR
+ LLDB_INVALID_REGNUM, // EDXEAX
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // EMM0L
+ LLDB_INVALID_REGNUM, // EMM1L
+ LLDB_INVALID_REGNUM, // EMM2L
+ LLDB_INVALID_REGNUM, // EMM3L
+ LLDB_INVALID_REGNUM, // EMM4L
+ LLDB_INVALID_REGNUM, // EMM5L
+ LLDB_INVALID_REGNUM, // EMM6L
+ LLDB_INVALID_REGNUM, // EMM7L
+ LLDB_INVALID_REGNUM, // EMM0H
+ LLDB_INVALID_REGNUM, // EMM1H
+ LLDB_INVALID_REGNUM, // EMM2H
+ LLDB_INVALID_REGNUM, // EMM3H
+ LLDB_INVALID_REGNUM, // EMM4H
+ LLDB_INVALID_REGNUM, // EMM5H
+ LLDB_INVALID_REGNUM, // EMM6H
+ LLDB_INVALID_REGNUM, // EMM7H
+ LLDB_INVALID_REGNUM, // MM00
+ LLDB_INVALID_REGNUM, // MM01
+ LLDB_INVALID_REGNUM, // MM10
+ LLDB_INVALID_REGNUM, // MM11
+ LLDB_INVALID_REGNUM, // MM20
+ LLDB_INVALID_REGNUM, // MM21
+ LLDB_INVALID_REGNUM, // MM30
+ LLDB_INVALID_REGNUM, // MM31
+ LLDB_INVALID_REGNUM, // MM40
+ LLDB_INVALID_REGNUM, // MM41
+ LLDB_INVALID_REGNUM, // MM50
+ LLDB_INVALID_REGNUM, // MM51
+ LLDB_INVALID_REGNUM, // MM60
+ LLDB_INVALID_REGNUM, // MM61
+ LLDB_INVALID_REGNUM, // MM70
+ LLDB_INVALID_REGNUM, // MM71
+ lldb_xmm8_x86_64, // XMM8
+ lldb_xmm9_x86_64, // XMM9
+ lldb_xmm10_x86_64, // XMM10
+ lldb_xmm11_x86_64, // XMM11
+ lldb_xmm12_x86_64, // XMM12
+ lldb_xmm13_x86_64, // XMM13
+ lldb_xmm14_x86_64, // XMM14
+ lldb_xmm15_x86_64, // XMM15
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM,
+ lldb_sil_x86_64, // SIL
+ lldb_dil_x86_64, // DIL
+ lldb_bpl_x86_64, // BPL
+ lldb_spl_x86_64, // SPL
+ lldb_rax_x86_64, // RAX
+ lldb_rbx_x86_64, // RBX
+ lldb_rcx_x86_64, // RCX
+ lldb_rdx_x86_64, // RDX
+ lldb_rsi_x86_64, // RSI
+ lldb_rdi_x86_64, // RDI
+ lldb_rbp_x86_64, // RBP
+ lldb_rsp_x86_64, // RSP
+ lldb_r8_x86_64, // R8
+ lldb_r9_x86_64, // R9
+ lldb_r10_x86_64, // R10
+ lldb_r11_x86_64, // R11
+ lldb_r12_x86_64, // R12
+ lldb_r13_x86_64, // R13
+ lldb_r14_x86_64, // R14
+ lldb_r15_x86_64, // R15
+ lldb_r8l_x86_64, // R8B
+ lldb_r9l_x86_64, // R9B
+ lldb_r10l_x86_64, // R10B
+ lldb_r11l_x86_64, // R11B
+ lldb_r12l_x86_64, // R12B
+ lldb_r13l_x86_64, // R13B
+ lldb_r14l_x86_64, // R14B
+ lldb_r15l_x86_64, // R15B
+ lldb_r8w_x86_64, // R8W
+ lldb_r9w_x86_64, // R9W
+ lldb_r10w_x86_64, // R10W
+ lldb_r11w_x86_64, // R11W
+ lldb_r12w_x86_64, // R12W
+ lldb_r13w_x86_64, // R13W
+ lldb_r14w_x86_64, // R14W
+ lldb_r15w_x86_64, // R15W
+ lldb_r8d_x86_64, // R8D
+ lldb_r9d_x86_64, // R9D
+ lldb_r10d_x86_64, // R10D
+ lldb_r11d_x86_64, // R11D
+ lldb_r12d_x86_64, // R12D
+ lldb_r13d_x86_64, // R13D
+ lldb_r14d_x86_64, // R14D
+ lldb_r15d_x86_64, // R15D
+ lldb_ymm0_x86_64, // AMD64_YMM0
+ lldb_ymm1_x86_64, // AMD64_YMM1
+ lldb_ymm2_x86_64, // AMD64_YMM2
+ lldb_ymm3_x86_64, // AMD64_YMM3
+ lldb_ymm4_x86_64, // AMD64_YMM4
+ lldb_ymm5_x86_64, // AMD64_YMM5
+ lldb_ymm6_x86_64, // AMD64_YMM6
+ lldb_ymm7_x86_64, // AMD64_YMM7
+ lldb_ymm8_x86_64, // AMD64_YMM8
+ lldb_ymm9_x86_64, // AMD64_YMM9
+ lldb_ymm10_x86_64, // AMD64_YMM10
+ lldb_ymm11_x86_64, // AMD64_YMM11
+ lldb_ymm12_x86_64, // AMD64_YMM12
+ lldb_ymm13_x86_64, // AMD64_YMM13
+ lldb_ymm14_x86_64, // AMD64_YMM14
+ lldb_ymm15_x86_64, // AMD64_YMM15
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_bnd0_x86_64, // BND0
+ lldb_bnd1_x86_64, // BND1
+ lldb_bnd2_x86_64 // BND2
+};
+
+uint32_t lldb_private::npdb::GetLLDBRegisterNumber(
+ llvm::Triple::ArchType arch_type, llvm::codeview::RegisterId register_id) {
+ switch (arch_type) {
+ case llvm::Triple::x86:
+ if (static_cast<uint16_t>(register_id) <
+ sizeof(g_code_view_to_lldb_registers_x86) /
+ sizeof(g_code_view_to_lldb_registers_x86[0]))
+ return g_code_view_to_lldb_registers_x86[static_cast<uint16_t>(
+ register_id)];
+
+ switch (register_id) {
+ case llvm::codeview::RegisterId::MXCSR:
+ return lldb_mxcsr_i386;
+ case llvm::codeview::RegisterId::BND0:
+ return lldb_bnd0_i386;
+ case llvm::codeview::RegisterId::BND1:
+ return lldb_bnd1_i386;
+ case llvm::codeview::RegisterId::BND2:
+ return lldb_bnd2_i386;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ case llvm::Triple::x86_64:
+ if (static_cast<uint16_t>(register_id) <
+ sizeof(g_code_view_to_lldb_registers_x86_64) /
+ sizeof(g_code_view_to_lldb_registers_x86_64[0]))
+ return g_code_view_to_lldb_registers_x86_64[static_cast<uint16_t>(
+ register_id)];
+
+ return LLDB_INVALID_REGNUM;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h
new file mode 100644
index 000000000000..b1c31e0c1785
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h
@@ -0,0 +1,24 @@
+//===-- CodeViewRegisterMapping.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_Plugins_SymbolFile_PDB_CodeViewRegisterMapping_h_
+#define lldb_Plugins_SymbolFile_PDB_CodeViewRegisterMapping_h_
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+
+namespace lldb_private {
+namespace npdb {
+
+uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type,
+ llvm::codeview::RegisterId register_id);
+
+} // namespace npdb
+} // namespace lldb_private
+
+#endif
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
index 67ea05767fde..1838204e4ca6 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
@@ -1,9 +1,8 @@
//===-- CompileUnitIndex.cpp ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -125,11 +124,20 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) {
uint16_t stream = descriptor.getModuleStreamIndex();
std::unique_ptr<llvm::msf::MappedBlockStream> stream_data =
m_index.pdb().createIndexedStream(stream);
+
+
+ std::unique_ptr<CompilandIndexItem>& cci = result.first->second;
+
+ if (!stream_data) {
+ llvm::pdb::ModuleDebugStreamRef debug_stream(descriptor, nullptr);
+ cci = llvm::make_unique<CompilandIndexItem>(PdbCompilandId{ modi }, debug_stream, std::move(descriptor));
+ return *cci;
+ }
+
llvm::pdb::ModuleDebugStreamRef debug_stream(descriptor,
std::move(stream_data));
- cantFail(debug_stream.reload());
- std::unique_ptr<CompilandIndexItem> &cci = result.first->second;
+ cantFail(debug_stream.reload());
cci = llvm::make_unique<CompilandIndexItem>(
PdbCompilandId{modi}, std::move(debug_stream), std::move(descriptor));
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h
index c965870da44b..44a1c8cdd9c2 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h
@@ -1,9 +1,8 @@
//===-- CompileUnitIndex.h --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
index 7b62530e4680..3d8bfb058721 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
@@ -1,15 +1,13 @@
//===-- DWARFLocationExpression.cpp -----------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DWARFLocationExpression.h"
-#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamBuffer.h"
@@ -24,6 +22,8 @@
#include "llvm/Support/Endian.h"
#include "PdbUtil.h"
+#include "CodeViewRegisterMapping.h"
+#include "PdbFPOProgramToDWARFExpression.h"
using namespace lldb;
using namespace lldb_private;
@@ -31,448 +31,6 @@ using namespace lldb_private::npdb;
using namespace llvm::codeview;
using namespace llvm::pdb;
-static const uint32_t g_code_view_to_lldb_registers_x86[] = {
- LLDB_INVALID_REGNUM, // NONE
- lldb_al_i386, // AL
- lldb_cl_i386, // CL
- lldb_dl_i386, // DL
- lldb_bl_i386, // BL
- lldb_ah_i386, // AH
- lldb_ch_i386, // CH
- lldb_dh_i386, // DH
- lldb_bh_i386, // BH
- lldb_ax_i386, // AX
- lldb_cx_i386, // CX
- lldb_dx_i386, // DX
- lldb_bx_i386, // BX
- lldb_sp_i386, // SP
- lldb_bp_i386, // BP
- lldb_si_i386, // SI
- lldb_di_i386, // DI
- lldb_eax_i386, // EAX
- lldb_ecx_i386, // ECX
- lldb_edx_i386, // EDX
- lldb_ebx_i386, // EBX
- lldb_esp_i386, // ESP
- lldb_ebp_i386, // EBP
- lldb_esi_i386, // ESI
- lldb_edi_i386, // EDI
- lldb_es_i386, // ES
- lldb_cs_i386, // CS
- lldb_ss_i386, // SS
- lldb_ds_i386, // DS
- lldb_fs_i386, // FS
- lldb_gs_i386, // GS
- LLDB_INVALID_REGNUM, // IP
- LLDB_INVALID_REGNUM, // FLAGS
- lldb_eip_i386, // EIP
- lldb_eflags_i386, // EFLAGS
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // TEMP
- LLDB_INVALID_REGNUM, // TEMPH
- LLDB_INVALID_REGNUM, // QUOTE
- LLDB_INVALID_REGNUM, // PCDR3
- LLDB_INVALID_REGNUM, // PCDR4
- LLDB_INVALID_REGNUM, // PCDR5
- LLDB_INVALID_REGNUM, // PCDR6
- LLDB_INVALID_REGNUM, // PCDR7
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // CR0
- LLDB_INVALID_REGNUM, // CR1
- LLDB_INVALID_REGNUM, // CR2
- LLDB_INVALID_REGNUM, // CR3
- LLDB_INVALID_REGNUM, // CR4
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_dr0_i386, // DR0
- lldb_dr1_i386, // DR1
- lldb_dr2_i386, // DR2
- lldb_dr3_i386, // DR3
- lldb_dr4_i386, // DR4
- lldb_dr5_i386, // DR5
- lldb_dr6_i386, // DR6
- lldb_dr7_i386, // DR7
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // GDTR
- LLDB_INVALID_REGNUM, // GDTL
- LLDB_INVALID_REGNUM, // IDTR
- LLDB_INVALID_REGNUM, // IDTL
- LLDB_INVALID_REGNUM, // LDTR
- LLDB_INVALID_REGNUM, // TR
- LLDB_INVALID_REGNUM, // PSEUDO1
- LLDB_INVALID_REGNUM, // PSEUDO2
- LLDB_INVALID_REGNUM, // PSEUDO3
- LLDB_INVALID_REGNUM, // PSEUDO4
- LLDB_INVALID_REGNUM, // PSEUDO5
- LLDB_INVALID_REGNUM, // PSEUDO6
- LLDB_INVALID_REGNUM, // PSEUDO7
- LLDB_INVALID_REGNUM, // PSEUDO8
- LLDB_INVALID_REGNUM, // PSEUDO9
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_st0_i386, // ST0
- lldb_st1_i386, // ST1
- lldb_st2_i386, // ST2
- lldb_st3_i386, // ST3
- lldb_st4_i386, // ST4
- lldb_st5_i386, // ST5
- lldb_st6_i386, // ST6
- lldb_st7_i386, // ST7
- LLDB_INVALID_REGNUM, // CTRL
- LLDB_INVALID_REGNUM, // STAT
- LLDB_INVALID_REGNUM, // TAG
- LLDB_INVALID_REGNUM, // FPIP
- LLDB_INVALID_REGNUM, // FPCS
- LLDB_INVALID_REGNUM, // FPDO
- LLDB_INVALID_REGNUM, // FPDS
- LLDB_INVALID_REGNUM, // ISEM
- LLDB_INVALID_REGNUM, // FPEIP
- LLDB_INVALID_REGNUM, // FPEDO
- lldb_mm0_i386, // MM0
- lldb_mm1_i386, // MM1
- lldb_mm2_i386, // MM2
- lldb_mm3_i386, // MM3
- lldb_mm4_i386, // MM4
- lldb_mm5_i386, // MM5
- lldb_mm6_i386, // MM6
- lldb_mm7_i386, // MM7
- lldb_xmm0_i386, // XMM0
- lldb_xmm1_i386, // XMM1
- lldb_xmm2_i386, // XMM2
- lldb_xmm3_i386, // XMM3
- lldb_xmm4_i386, // XMM4
- lldb_xmm5_i386, // XMM5
- lldb_xmm6_i386, // XMM6
- lldb_xmm7_i386 // XMM7
-};
-
-static const uint32_t g_code_view_to_lldb_registers_x86_64[] = {
- LLDB_INVALID_REGNUM, // NONE
- lldb_al_x86_64, // AL
- lldb_cl_x86_64, // CL
- lldb_dl_x86_64, // DL
- lldb_bl_x86_64, // BL
- lldb_ah_x86_64, // AH
- lldb_ch_x86_64, // CH
- lldb_dh_x86_64, // DH
- lldb_bh_x86_64, // BH
- lldb_ax_x86_64, // AX
- lldb_cx_x86_64, // CX
- lldb_dx_x86_64, // DX
- lldb_bx_x86_64, // BX
- lldb_sp_x86_64, // SP
- lldb_bp_x86_64, // BP
- lldb_si_x86_64, // SI
- lldb_di_x86_64, // DI
- lldb_eax_x86_64, // EAX
- lldb_ecx_x86_64, // ECX
- lldb_edx_x86_64, // EDX
- lldb_ebx_x86_64, // EBX
- lldb_esp_x86_64, // ESP
- lldb_ebp_x86_64, // EBP
- lldb_esi_x86_64, // ESI
- lldb_edi_x86_64, // EDI
- lldb_es_x86_64, // ES
- lldb_cs_x86_64, // CS
- lldb_ss_x86_64, // SS
- lldb_ds_x86_64, // DS
- lldb_fs_x86_64, // FS
- lldb_gs_x86_64, // GS
- LLDB_INVALID_REGNUM, // IP
- LLDB_INVALID_REGNUM, // FLAGS
- LLDB_INVALID_REGNUM, // EIP
- LLDB_INVALID_REGNUM, // EFLAGS
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // TEMP
- LLDB_INVALID_REGNUM, // TEMPH
- LLDB_INVALID_REGNUM, // QUOTE
- LLDB_INVALID_REGNUM, // PCDR3
- LLDB_INVALID_REGNUM, // PCDR4
- LLDB_INVALID_REGNUM, // PCDR5
- LLDB_INVALID_REGNUM, // PCDR6
- LLDB_INVALID_REGNUM, // PCDR7
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // CR0
- LLDB_INVALID_REGNUM, // CR1
- LLDB_INVALID_REGNUM, // CR2
- LLDB_INVALID_REGNUM, // CR3
- LLDB_INVALID_REGNUM, // CR4
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_dr0_x86_64, // DR0
- lldb_dr1_x86_64, // DR1
- lldb_dr2_x86_64, // DR2
- lldb_dr3_x86_64, // DR3
- lldb_dr4_x86_64, // DR4
- lldb_dr5_x86_64, // DR5
- lldb_dr6_x86_64, // DR6
- lldb_dr7_x86_64, // DR7
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // GDTR
- LLDB_INVALID_REGNUM, // GDTL
- LLDB_INVALID_REGNUM, // IDTR
- LLDB_INVALID_REGNUM, // IDTL
- LLDB_INVALID_REGNUM, // LDTR
- LLDB_INVALID_REGNUM, // TR
- LLDB_INVALID_REGNUM, // PSEUDO1
- LLDB_INVALID_REGNUM, // PSEUDO2
- LLDB_INVALID_REGNUM, // PSEUDO3
- LLDB_INVALID_REGNUM, // PSEUDO4
- LLDB_INVALID_REGNUM, // PSEUDO5
- LLDB_INVALID_REGNUM, // PSEUDO6
- LLDB_INVALID_REGNUM, // PSEUDO7
- LLDB_INVALID_REGNUM, // PSEUDO8
- LLDB_INVALID_REGNUM, // PSEUDO9
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_st0_x86_64, // ST0
- lldb_st1_x86_64, // ST1
- lldb_st2_x86_64, // ST2
- lldb_st3_x86_64, // ST3
- lldb_st4_x86_64, // ST4
- lldb_st5_x86_64, // ST5
- lldb_st6_x86_64, // ST6
- lldb_st7_x86_64, // ST7
- LLDB_INVALID_REGNUM, // CTRL
- LLDB_INVALID_REGNUM, // STAT
- LLDB_INVALID_REGNUM, // TAG
- LLDB_INVALID_REGNUM, // FPIP
- LLDB_INVALID_REGNUM, // FPCS
- LLDB_INVALID_REGNUM, // FPDO
- LLDB_INVALID_REGNUM, // FPDS
- LLDB_INVALID_REGNUM, // ISEM
- LLDB_INVALID_REGNUM, // FPEIP
- LLDB_INVALID_REGNUM, // FPEDO
- lldb_mm0_x86_64, // MM0
- lldb_mm1_x86_64, // MM1
- lldb_mm2_x86_64, // MM2
- lldb_mm3_x86_64, // MM3
- lldb_mm4_x86_64, // MM4
- lldb_mm5_x86_64, // MM5
- lldb_mm6_x86_64, // MM6
- lldb_mm7_x86_64, // MM7
- lldb_xmm0_x86_64, // XMM0
- lldb_xmm1_x86_64, // XMM1
- lldb_xmm2_x86_64, // XMM2
- lldb_xmm3_x86_64, // XMM3
- lldb_xmm4_x86_64, // XMM4
- lldb_xmm5_x86_64, // XMM5
- lldb_xmm6_x86_64, // XMM6
- lldb_xmm7_x86_64, // XMM7
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM,
- lldb_mxcsr_x86_64, // MXCSR
- LLDB_INVALID_REGNUM, // EDXEAX
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // EMM0L
- LLDB_INVALID_REGNUM, // EMM1L
- LLDB_INVALID_REGNUM, // EMM2L
- LLDB_INVALID_REGNUM, // EMM3L
- LLDB_INVALID_REGNUM, // EMM4L
- LLDB_INVALID_REGNUM, // EMM5L
- LLDB_INVALID_REGNUM, // EMM6L
- LLDB_INVALID_REGNUM, // EMM7L
- LLDB_INVALID_REGNUM, // EMM0H
- LLDB_INVALID_REGNUM, // EMM1H
- LLDB_INVALID_REGNUM, // EMM2H
- LLDB_INVALID_REGNUM, // EMM3H
- LLDB_INVALID_REGNUM, // EMM4H
- LLDB_INVALID_REGNUM, // EMM5H
- LLDB_INVALID_REGNUM, // EMM6H
- LLDB_INVALID_REGNUM, // EMM7H
- LLDB_INVALID_REGNUM, // MM00
- LLDB_INVALID_REGNUM, // MM01
- LLDB_INVALID_REGNUM, // MM10
- LLDB_INVALID_REGNUM, // MM11
- LLDB_INVALID_REGNUM, // MM20
- LLDB_INVALID_REGNUM, // MM21
- LLDB_INVALID_REGNUM, // MM30
- LLDB_INVALID_REGNUM, // MM31
- LLDB_INVALID_REGNUM, // MM40
- LLDB_INVALID_REGNUM, // MM41
- LLDB_INVALID_REGNUM, // MM50
- LLDB_INVALID_REGNUM, // MM51
- LLDB_INVALID_REGNUM, // MM60
- LLDB_INVALID_REGNUM, // MM61
- LLDB_INVALID_REGNUM, // MM70
- LLDB_INVALID_REGNUM, // MM71
- lldb_xmm8_x86_64, // XMM8
- lldb_xmm9_x86_64, // XMM9
- lldb_xmm10_x86_64, // XMM10
- lldb_xmm11_x86_64, // XMM11
- lldb_xmm12_x86_64, // XMM12
- lldb_xmm13_x86_64, // XMM13
- lldb_xmm14_x86_64, // XMM14
- lldb_xmm15_x86_64, // XMM15
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM,
- lldb_sil_x86_64, // SIL
- lldb_dil_x86_64, // DIL
- lldb_bpl_x86_64, // BPL
- lldb_spl_x86_64, // SPL
- lldb_rax_x86_64, // RAX
- lldb_rbx_x86_64, // RBX
- lldb_rcx_x86_64, // RCX
- lldb_rdx_x86_64, // RDX
- lldb_rsi_x86_64, // RSI
- lldb_rdi_x86_64, // RDI
- lldb_rbp_x86_64, // RBP
- lldb_rsp_x86_64, // RSP
- lldb_r8_x86_64, // R8
- lldb_r9_x86_64, // R9
- lldb_r10_x86_64, // R10
- lldb_r11_x86_64, // R11
- lldb_r12_x86_64, // R12
- lldb_r13_x86_64, // R13
- lldb_r14_x86_64, // R14
- lldb_r15_x86_64, // R15
- lldb_r8l_x86_64, // R8B
- lldb_r9l_x86_64, // R9B
- lldb_r10l_x86_64, // R10B
- lldb_r11l_x86_64, // R11B
- lldb_r12l_x86_64, // R12B
- lldb_r13l_x86_64, // R13B
- lldb_r14l_x86_64, // R14B
- lldb_r15l_x86_64, // R15B
- lldb_r8w_x86_64, // R8W
- lldb_r9w_x86_64, // R9W
- lldb_r10w_x86_64, // R10W
- lldb_r11w_x86_64, // R11W
- lldb_r12w_x86_64, // R12W
- lldb_r13w_x86_64, // R13W
- lldb_r14w_x86_64, // R14W
- lldb_r15w_x86_64, // R15W
- lldb_r8d_x86_64, // R8D
- lldb_r9d_x86_64, // R9D
- lldb_r10d_x86_64, // R10D
- lldb_r11d_x86_64, // R11D
- lldb_r12d_x86_64, // R12D
- lldb_r13d_x86_64, // R13D
- lldb_r14d_x86_64, // R14D
- lldb_r15d_x86_64, // R15D
- lldb_ymm0_x86_64, // AMD64_YMM0
- lldb_ymm1_x86_64, // AMD64_YMM1
- lldb_ymm2_x86_64, // AMD64_YMM2
- lldb_ymm3_x86_64, // AMD64_YMM3
- lldb_ymm4_x86_64, // AMD64_YMM4
- lldb_ymm5_x86_64, // AMD64_YMM5
- lldb_ymm6_x86_64, // AMD64_YMM6
- lldb_ymm7_x86_64, // AMD64_YMM7
- lldb_ymm8_x86_64, // AMD64_YMM8
- lldb_ymm9_x86_64, // AMD64_YMM9
- lldb_ymm10_x86_64, // AMD64_YMM10
- lldb_ymm11_x86_64, // AMD64_YMM11
- lldb_ymm12_x86_64, // AMD64_YMM12
- lldb_ymm13_x86_64, // AMD64_YMM13
- lldb_ymm14_x86_64, // AMD64_YMM14
- lldb_ymm15_x86_64, // AMD64_YMM15
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_bnd0_x86_64, // BND0
- lldb_bnd1_x86_64, // BND1
- lldb_bnd2_x86_64 // BND2
-};
-
-uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type,
- llvm::codeview::RegisterId register_id) {
- switch (arch_type) {
- case llvm::Triple::x86:
- if (static_cast<uint16_t>(register_id) <
- sizeof(g_code_view_to_lldb_registers_x86) /
- sizeof(g_code_view_to_lldb_registers_x86[0]))
- return g_code_view_to_lldb_registers_x86[static_cast<uint16_t>(
- register_id)];
-
- switch (register_id) {
- case llvm::codeview::RegisterId::MXCSR:
- return lldb_mxcsr_i386;
- case llvm::codeview::RegisterId::BND0:
- return lldb_bnd0_i386;
- case llvm::codeview::RegisterId::BND1:
- return lldb_bnd1_i386;
- case llvm::codeview::RegisterId::BND2:
- return lldb_bnd2_i386;
- default:
- return LLDB_INVALID_REGNUM;
- }
- case llvm::Triple::x86_64:
- if (static_cast<uint16_t>(register_id) <
- sizeof(g_code_view_to_lldb_registers_x86_64) /
- sizeof(g_code_view_to_lldb_registers_x86_64[0]))
- return g_code_view_to_lldb_registers_x86_64[static_cast<uint16_t>(
- register_id)];
-
- return LLDB_INVALID_REGNUM;
- default:
- return LLDB_INVALID_REGNUM;
- }
-}
-
uint32_t GetGenericRegisterNumber(llvm::codeview::RegisterId register_id) {
if (register_id == llvm::codeview::RegisterId::VFRAME)
return LLDB_REGNUM_GENERIC_FP;
@@ -553,13 +111,13 @@ static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module,
uint32_t address_size = architecture.GetAddressByteSize();
uint32_t byte_size = architecture.GetDataByteSize();
if (byte_order == eByteOrderInvalid || address_size == 0)
- return DWARFExpression(nullptr);
+ return DWARFExpression();
RegisterKind register_kind = eRegisterKindDWARF;
StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
if (!writer(stream, register_kind))
- return DWARFExpression(nullptr);
+ return DWARFExpression();
DataBufferSP buffer =
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
@@ -610,6 +168,33 @@ DWARFExpression lldb_private::npdb::MakeRegRelLocationExpression(
return MakeRegisterBasedLocationExpressionInternal(reg, offset, module);
}
+static bool EmitVFrameEvaluationDWARFExpression(
+ llvm::StringRef program, llvm::Triple::ArchType arch_type, Stream &stream) {
+ // VFrame value always stored in $TO pseudo-register
+ return TranslateFPOProgramToDWARFExpression(program, "$T0", arch_type,
+ stream);
+}
+
+DWARFExpression lldb_private::npdb::MakeVFrameRelLocationExpression(
+ llvm::StringRef fpo_program, int32_t offset, lldb::ModuleSP module) {
+ return MakeLocationExpressionInternal(
+ module, [&](Stream &stream, RegisterKind &register_kind) -> bool {
+ const ArchSpec &architecture = module->GetArchitecture();
+
+ if (!EmitVFrameEvaluationDWARFExpression(fpo_program, architecture.GetMachine(),
+ stream))
+ return false;
+
+ stream.PutHex8(llvm::dwarf::DW_OP_consts);
+ stream.PutSLEB128(offset);
+ stream.PutHex8(llvm::dwarf::DW_OP_plus);
+
+ register_kind = eRegisterKindLLDB;
+
+ return true;
+ });
+}
+
DWARFExpression lldb_private::npdb::MakeGlobalLocationExpression(
uint16_t section, uint32_t offset, ModuleSP module) {
assert(section > 0);
@@ -622,13 +207,7 @@ DWARFExpression lldb_private::npdb::MakeGlobalLocationExpression(
SectionList *section_list = module->GetSectionList();
assert(section_list);
- // Section indices in PDB are 1-based, but in DWARF they are 0-based, so
- // we need to subtract 1.
- uint32_t section_idx = section - 1;
- if (section_idx >= section_list->GetSize())
- return false;
-
- auto section_ptr = section_list->GetSectionAtIndex(section_idx);
+ auto section_ptr = section_list->FindSectionByID(section);
if (!section_ptr)
return false;
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
index 670e95ee8e3c..c37d715babdc 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
@@ -1,9 +1,8 @@
//===-- DWARFLocationExpression.h -------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -31,6 +30,9 @@ MakeEnregisteredLocationExpression(llvm::codeview::RegisterId reg,
DWARFExpression MakeRegRelLocationExpression(llvm::codeview::RegisterId reg,
int32_t offset,
lldb::ModuleSP module);
+DWARFExpression MakeVFrameRelLocationExpression(llvm::StringRef fpo_program,
+ int32_t offset,
+ lldb::ModuleSP module);
DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset,
lldb::ModuleSP module);
DWARFExpression MakeConstantLocationExpression(
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 8917fd092385..4991be8e70ce 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -205,13 +205,17 @@ GetNestedTagDefinition(const NestedTypeRecord &Record,
return std::move(child);
}
+static bool IsAnonymousNamespaceName(llvm::StringRef name) {
+ return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
+}
+
PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index)
: m_index(index), m_clang(GetClangASTContext(obj)) {
BuildParentMap();
}
-clang::DeclContext &PdbAstBuilder::GetTranslationUnitDecl() {
- return *m_clang.GetTranslationUnitDecl();
+lldb_private::CompilerDeclContext PdbAstBuilder::GetTranslationUnitDecl() {
+ return ToCompilerDeclContext(*m_clang.GetTranslationUnitDecl());
}
std::pair<clang::DeclContext *, std::string>
@@ -256,7 +260,7 @@ PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) {
for (llvm::ms_demangle::Node *scope : scopes) {
auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope);
std::string str = nii->toString();
- context = m_clang.GetUniqueNamespaceDeclaration(str.c_str(), context);
+ context = GetOrCreateNamespaceDecl(str.c_str(), *context);
}
return {context, uname};
}
@@ -488,7 +492,7 @@ clang::Decl *PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) {
if (uid.kind() == PdbSymUidKind::CompilandSym) {
if (uid.asCompilandSym().offset == 0)
- return &GetTranslationUnitDecl();
+ return FromCompilerDeclContext(GetTranslationUnitDecl());
}
clang::Decl *decl = GetOrCreateDeclForUid(uid);
@@ -503,7 +507,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {
MSVCUndecoratedNameParser parser(name);
llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
- clang::DeclContext *context = &GetTranslationUnitDecl();
+ auto context = FromCompilerDeclContext(GetTranslationUnitDecl());
llvm::StringRef uname = specs.back().GetBaseName();
specs = specs.drop_back();
@@ -525,7 +529,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {
// If that fails, treat it as a series of namespaces.
for (const MSVCUndecoratedNameSpecifier &spec : specs) {
std::string ns_name = spec.GetBaseName().str();
- context = m_clang.GetUniqueNamespaceDeclaration(ns_name.c_str(), context);
+ context = GetOrCreateNamespaceDecl(ns_name.c_str(), *context);
}
return {context, uname};
}
@@ -544,7 +548,7 @@ PdbAstBuilder::GetParentDeclContextForSymbol(const CVSymbol &sym) {
StringView name{pub->Name.begin(), pub->Name.size()};
llvm::ms_demangle::SymbolNode *node = demangler.parse(name);
if (!node)
- return &GetTranslationUnitDecl();
+ return FromCompilerDeclContext(GetTranslationUnitDecl());
llvm::ArrayRef<llvm::ms_demangle::Node *> name_components{
node->Name->Components->Nodes, node->Name->Components->Count - 1};
@@ -565,10 +569,10 @@ PdbAstBuilder::GetParentDeclContextForSymbol(const CVSymbol &sym) {
}
// It's not a type. It must be a series of namespaces.
- clang::DeclContext *context = &GetTranslationUnitDecl();
+ auto context = FromCompilerDeclContext(GetTranslationUnitDecl());
while (!name_components.empty()) {
std::string ns = name_components.front()->toString();
- context = m_clang.GetUniqueNamespaceDeclaration(ns.c_str(), context);
+ context = GetOrCreateNamespaceDecl(ns.c_str(), *context);
name_components = name_components.drop_front();
}
return context;
@@ -593,7 +597,7 @@ clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) {
PdbTypeSymId type_id = uid.asTypeSym();
auto iter = m_parent_types.find(type_id.index);
if (iter == m_parent_types.end())
- return &GetTranslationUnitDecl();
+ return FromCompilerDeclContext(GetTranslationUnitDecl());
return GetOrCreateDeclContextForUid(PdbTypeSymId(iter->second));
}
case PdbSymUidKind::FieldListMember:
@@ -631,7 +635,7 @@ clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) {
default:
break;
}
- return &GetTranslationUnitDecl();
+ return FromCompilerDeclContext(GetTranslationUnitDecl());
}
bool PdbAstBuilder::CompleteType(clang::QualType qt) {
@@ -805,9 +809,10 @@ clang::Decl *PdbAstBuilder::TryGetDecl(PdbSymUid uid) const {
}
clang::NamespaceDecl *
-PdbAstBuilder::GetOrCreateNamespaceDecl(llvm::StringRef name,
+PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,
clang::DeclContext &context) {
- return m_clang.GetUniqueNamespaceDeclaration(name.str().c_str(), &context);
+ return m_clang.GetUniqueNamespaceDeclaration(
+ IsAnonymousNamespaceName(name) ? nullptr : name, &context);
}
clang::BlockDecl *
@@ -861,7 +866,8 @@ clang::VarDecl *PdbAstBuilder::GetOrCreateVariableDecl(PdbGlobalSymId var_id) {
return llvm::dyn_cast<clang::VarDecl>(decl);
CVSymbol sym = m_index.ReadSymbolRecord(var_id);
- return CreateVariableDecl(PdbSymUid(var_id), sym, GetTranslationUnitDecl());
+ auto context = FromCompilerDeclContext(GetTranslationUnitDecl());
+ return CreateVariableDecl(PdbSymUid(var_id), sym, *context);
}
clang::TypedefNameDecl *
@@ -933,7 +939,14 @@ clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) {
if (cvt.kind() == LF_PROCEDURE) {
ProcedureRecord pr;
llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));
- return CreateProcedureType(pr);
+ return CreateFunctionType(pr.ArgumentList, pr.ReturnType, pr.CallConv);
+ }
+
+ if (cvt.kind() == LF_MFUNCTION) {
+ MemberFunctionRecord mfr;
+ llvm::cantFail(
+ TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));
+ return CreateFunctionType(mfr.ArgumentList, mfr.ReturnType, mfr.CallConv);
}
return {};
@@ -1117,10 +1130,11 @@ clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) {
return clang::QualType::getFromOpaquePtr(array_ct.GetOpaqueQualType());
}
-clang::QualType
-PdbAstBuilder::CreateProcedureType(const ProcedureRecord &proc) {
+clang::QualType PdbAstBuilder::CreateFunctionType(
+ TypeIndex args_type_idx, TypeIndex return_type_idx,
+ llvm::codeview::CallingConvention calling_convention) {
TpiStream &stream = m_index.tpi();
- CVType args_cvt = stream.getType(proc.ArgumentList);
+ CVType args_cvt = stream.getType(args_type_idx);
ArgListRecord args;
llvm::cantFail(
TypeDeserializer::deserializeAs<ArgListRecord>(args_cvt, args));
@@ -1138,10 +1152,10 @@ PdbAstBuilder::CreateProcedureType(const ProcedureRecord &proc) {
arg_types.push_back(ToCompilerType(arg_type));
}
- clang::QualType return_type = GetOrCreateType(proc.ReturnType);
+ clang::QualType return_type = GetOrCreateType(return_type_idx);
llvm::Optional<clang::CallingConv> cc =
- TranslateCallingConvention(proc.CallConv);
+ TranslateCallingConvention(calling_convention);
if (!cc)
return {};
@@ -1340,6 +1354,10 @@ PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) {
return {&m_clang, &context};
}
+clang::Decl * PdbAstBuilder::FromCompilerDecl(CompilerDecl decl) {
+ return static_cast<clang::Decl *>(decl.GetOpaqueDecl());
+}
+
clang::DeclContext *
PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) {
return static_cast<clang::DeclContext *>(context.GetOpaqueDeclContext());
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
index e3c0346f935e..67d024741e0d 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -1,9 +1,8 @@
//===-- PdbAstBuilder.h -----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -51,19 +50,15 @@ struct DeclStatus {
class PdbAstBuilder {
public:
- //------------------------------------------------------------------
// Constructors and Destructors
- //------------------------------------------------------------------
PdbAstBuilder(ObjectFile &obj, PdbIndex &index);
- clang::DeclContext &GetTranslationUnitDecl();
+ lldb_private::CompilerDeclContext GetTranslationUnitDecl();
clang::Decl *GetOrCreateDeclForUid(PdbSymUid uid);
clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid);
clang::DeclContext *GetParentDeclContext(PdbSymUid uid);
- clang::NamespaceDecl *GetOrCreateNamespaceDecl(llvm::StringRef name,
- clang::DeclContext &context);
clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id);
clang::BlockDecl *GetOrCreateBlockDecl(PdbCompilandSymId block_id);
clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id,
@@ -81,6 +76,7 @@ public:
CompilerDecl ToCompilerDecl(clang::Decl &decl);
CompilerType ToCompilerType(clang::QualType qt);
CompilerDeclContext ToCompilerDeclContext(clang::DeclContext &context);
+ clang::Decl * FromCompilerDecl(CompilerDecl decl);
clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context);
ClangASTContext &clang() { return m_clang; }
@@ -103,7 +99,8 @@ private:
clang::QualType CreateEnumType(PdbTypeSymId id,
const llvm::codeview::EnumRecord &record);
clang::QualType
- CreateProcedureType(const llvm::codeview::ProcedureRecord &proc);
+ CreateFunctionType(TypeIndex args_type_idx, TypeIndex return_type_idx,
+ llvm::codeview::CallingConvention calling_convention);
clang::QualType CreateType(PdbTypeSymId type);
void CreateFunctionParameters(PdbCompilandSymId func_id,
@@ -116,6 +113,9 @@ private:
clang::DeclContext *
GetParentDeclContextForSymbol(const llvm::codeview::CVSymbol &sym);
+ clang::NamespaceDecl *GetOrCreateNamespaceDecl(const char *name,
+ clang::DeclContext &context);
+
void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent);
void ParseDeclsForSimpleContext(clang::DeclContext &context);
void ParseBlockChildren(PdbCompilandSymId block_id);
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
new file mode 100644
index 000000000000..79dd010ff311
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
@@ -0,0 +1,137 @@
+//===-- PdbFPOProgramToDWARFExpression.cpp ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "PdbFPOProgramToDWARFExpression.h"
+#include "CodeViewRegisterMapping.h"
+
+#include "lldb/Core/StreamBuffer.h"
+#include "lldb/Symbol/PostfixExpression.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/Stream.h"
+#include "llvm/ADT/DenseMap.h"
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/EnumTables.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::postfix;
+
+static uint32_t ResolveLLDBRegisterNum(llvm::StringRef reg_name, llvm::Triple::ArchType arch_type) {
+ // lookup register name to get lldb register number
+ llvm::codeview::CPUType cpu_type;
+ switch (arch_type) {
+ case llvm::Triple::ArchType::aarch64:
+ cpu_type = llvm::codeview::CPUType::ARM64;
+ break;
+
+ default:
+ cpu_type = llvm::codeview::CPUType::X64;
+ break;
+ }
+
+ llvm::ArrayRef<llvm::EnumEntry<uint16_t>> register_names =
+ llvm::codeview::getRegisterNames(cpu_type);
+ auto it = llvm::find_if(
+ register_names,
+ [&reg_name](const llvm::EnumEntry<uint16_t> &register_entry) {
+ return reg_name.compare_lower(register_entry.Name) == 0;
+ });
+
+ if (it == register_names.end())
+ return LLDB_INVALID_REGNUM;
+
+ auto reg_id = static_cast<llvm::codeview::RegisterId>(it->Value);
+ return npdb::GetLLDBRegisterNumber(arch_type, reg_id);
+}
+
+static bool ParseFPOSingleAssignmentProgram(llvm::StringRef program,
+ llvm::BumpPtrAllocator &alloc,
+ llvm::StringRef &register_name,
+ Node *&ast) {
+ // lvalue of assignment is always first token
+ // rvalue program goes next
+ std::tie(register_name, program) = getToken(program);
+ if (register_name.empty())
+ return false;
+
+ ast = Parse(program, alloc);
+ return ast != nullptr;
+}
+
+static Node *ParseFPOProgram(llvm::StringRef program,
+ llvm::StringRef register_name,
+ llvm::Triple::ArchType arch_type,
+ llvm::BumpPtrAllocator &alloc) {
+ llvm::DenseMap<llvm::StringRef, Node *> dependent_programs;
+
+ size_t cur = 0;
+ while (true) {
+ size_t assign_index = program.find('=', cur);
+ if (assign_index == llvm::StringRef::npos) {
+ llvm::StringRef tail = program.slice(cur, llvm::StringRef::npos);
+ if (!tail.trim().empty()) {
+ // missing assign operator
+ return nullptr;
+ }
+ break;
+ }
+ llvm::StringRef assignment_program = program.slice(cur, assign_index);
+
+ llvm::StringRef lvalue_name;
+ Node *rvalue_ast = nullptr;
+ if (!ParseFPOSingleAssignmentProgram(assignment_program, alloc, lvalue_name,
+ rvalue_ast)) {
+ return nullptr;
+ }
+
+ lldbassert(rvalue_ast);
+
+ // Emplace valid dependent subtrees to make target assignment independent
+ // from predecessors. Resolve all other SymbolNodes as registers.
+ bool success =
+ ResolveSymbols(rvalue_ast, [&](SymbolNode &symbol) -> Node * {
+ if (Node *node = dependent_programs.lookup(symbol.GetName()))
+ return node;
+ uint32_t reg_num =
+ ResolveLLDBRegisterNum(symbol.GetName().drop_front(1), arch_type);
+
+ if (reg_num == LLDB_INVALID_REGNUM)
+ return nullptr;
+
+ return MakeNode<RegisterNode>(alloc, reg_num);
+ });
+ if (!success)
+ return nullptr;
+
+ if (lvalue_name == register_name) {
+ // found target assignment program - no need to parse further
+ return rvalue_ast;
+ }
+
+ dependent_programs[lvalue_name] = rvalue_ast;
+ cur = assign_index + 1;
+ }
+
+ return nullptr;
+}
+
+bool lldb_private::npdb::TranslateFPOProgramToDWARFExpression(
+ llvm::StringRef program, llvm::StringRef register_name,
+ llvm::Triple::ArchType arch_type, Stream &stream) {
+ llvm::BumpPtrAllocator node_alloc;
+ Node *target_program =
+ ParseFPOProgram(program, register_name, arch_type, node_alloc);
+ if (target_program == nullptr) {
+ return false;
+ }
+
+ ToDWARF(*target_program, stream);
+ return true;
+}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h
new file mode 100644
index 000000000000..107e26fb04cb
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h
@@ -0,0 +1,28 @@
+//===-- PdbFPOProgramToDWARFExpression.h ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_Plugins_SymbolFile_PDB_PDBFPOProgramToDWARFExpression_h_
+#define lldb_Plugins_SymbolFile_PDB_PDBFPOProgramToDWARFExpression_h_
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+
+namespace lldb_private {
+class Stream;
+
+namespace npdb {
+
+bool TranslateFPOProgramToDWARFExpression(llvm::StringRef program,
+ llvm::StringRef register_name,
+ llvm::Triple::ArchType arch_type,
+ lldb_private::Stream &stream);
+
+} // namespace npdb
+} // namespace lldb_private
+
+#endif
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp
index 9f5dab6c2e84..ba9a95b16e18 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp
@@ -1,9 +1,8 @@
//===-- PdbIndex.cpp --------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -133,9 +132,8 @@ void PdbIndex::BuildAddrToSymbolMap(CompilandIndexItem &cci) {
PdbCompilandSymId cu_sym_id(modi, iter.offset());
- // If the debug info is incorrect, we could have multiple symbols with the
- // same address. So use try_emplace instead of insert, and the first one
- // will win.
+ // It's rare, but we could have multiple symbols with the same address
+ // because of identical comdat folding. Right now, the first one will win.
cci.m_symbols_by_va.insert(std::make_pair(va, PdbSymUid(cu_sym_id)));
}
}
@@ -187,8 +185,6 @@ std::vector<SymbolAndUid> PdbIndex::FindSymbolsByVa(lldb::addr_t va) {
}
CVSymbol PdbIndex::ReadSymbolRecord(PdbCompilandSymId cu_sym) const {
- // We need to subtract 4 here to adjust for the codeview debug magic
- // at the beginning of the debug info stream.
const CompilandIndexItem *cci = compilands().GetCompiland(cu_sym.modi);
auto iter = cci->m_debug_stream.getSymbolArray().at(cu_sym.offset);
lldbassert(iter != cci->m_debug_stream.getSymbolArray().end());
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
index 839d4e6606e4..b30e7870bbdb 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
@@ -1,9 +1,8 @@
//===-- PdbIndex.h ----------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -115,6 +114,7 @@ public:
create(std::unique_ptr<llvm::pdb::PDBFile>);
void SetLoadAddress(lldb::addr_t addr) { m_load_address = addr; }
+ lldb::addr_t GetLoadAddress() const { return m_load_address; }
void ParseSectionContribs();
llvm::pdb::PDBFile &pdb() { return *m_file; }
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp
index e5424568da47..e5ad23f813eb 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp
@@ -1,9 +1,8 @@
//===-- PdbSymUid.cpp -------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
index 1166bee4e327..7252d63c1ab4 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
@@ -1,9 +1,8 @@
//===-- PdbSymUid.h ---------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// A unique identification scheme for Pdb records.
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
index 317725dd250e..1f5c97da81cf 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
@@ -1,9 +1,8 @@
//===-- PdbUtil.cpp ---------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -15,9 +14,11 @@
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
+#include "lldb/Symbol/Block.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/lldb-enumerations.h"
@@ -43,7 +44,7 @@ MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range,
gaps = gaps.drop_front();
}
- result.Append(start, end);
+ result.Append(start, end - start);
return result;
}
@@ -507,8 +508,78 @@ VariableInfo lldb_private::npdb::GetVariableNameInfo(CVSymbol sym) {
return {};
}
+static llvm::FixedStreamArray<FrameData>::Iterator
+GetCorrespondingFrameData(lldb::addr_t load_addr,
+ const DebugFrameDataSubsectionRef &fpo_data,
+ const Variable::RangeList &ranges) {
+ lldbassert(!ranges.IsEmpty());
+
+ // assume that all variable ranges correspond to one frame data
+ using RangeListEntry = Variable::RangeList::Entry;
+ const RangeListEntry &range = ranges.GetEntryRef(0);
+
+ auto it = fpo_data.begin();
+
+ // start by searching first frame data range containing variable range
+ for (; it != fpo_data.end(); ++it) {
+ RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize);
+
+ if (fd_range.Contains(range)) {
+ break;
+ }
+ }
+
+ // then first most nested entry that still contains variable range
+ auto found = it;
+ for (; it != fpo_data.end(); ++it) {
+ RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize);
+
+ if (!fd_range.Contains(range)) {
+ break;
+ }
+ found = it;
+ }
+
+ return found;
+}
+
+static bool GetFrameDataProgram(PdbIndex &index,
+ const Variable::RangeList &ranges,
+ llvm::StringRef &out_program) {
+ const DebugFrameDataSubsectionRef &new_fpo_data =
+ index.dbi().getNewFpoRecords();
+
+ auto frame_data_it =
+ GetCorrespondingFrameData(index.GetLoadAddress(), new_fpo_data, ranges);
+ if (frame_data_it == new_fpo_data.end())
+ return false;
+
+ PDBStringTable &strings = cantFail(index.pdb().getStringTable());
+ out_program = cantFail(strings.getStringForID(frame_data_it->FrameFunc));
+ return true;
+}
+
+static RegisterId GetBaseFrameRegister(PdbIndex &index,
+ PdbCompilandSymId frame_proc_id,
+ bool is_parameter) {
+ CVSymbol frame_proc_cvs = index.ReadSymbolRecord(frame_proc_id);
+ lldbassert(frame_proc_cvs.kind() == S_FRAMEPROC);
+
+ FrameProcSym frame_proc(SymbolRecordKind::FrameProcSym);
+ cantFail(SymbolDeserializer::deserializeAs<FrameProcSym>(frame_proc_cvs,
+ frame_proc));
+
+ CPUType cpu_type = index.compilands()
+ .GetCompiland(frame_proc_id.modi)
+ ->m_compile_opts->Machine;
+
+ return is_parameter ? frame_proc.getParamFramePtrReg(cpu_type)
+ : frame_proc.getLocalFramePtrReg(cpu_type);
+}
+
VariableInfo lldb_private::npdb::GetVariableLocationInfo(
- PdbIndex &index, PdbCompilandSymId var_id, lldb::ModuleSP module) {
+ PdbIndex &index, PdbCompilandSymId var_id, Block &block,
+ lldb::ModuleSP module) {
CVSymbol sym = index.ReadSymbolRecord(var_id);
@@ -543,13 +614,69 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo(
SymbolRecordKind::DefRangeFramePointerRelSym);
cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>(
loc_specifier_cvs, loc));
- // FIXME: The register needs to come from the S_FRAMEPROC symbol.
- result.location =
- MakeRegRelLocationExpression(RegisterId::RSP, loc.Offset, module);
- result.ranges = MakeRangeList(index, loc.Range, loc.Gaps);
- } else {
- // FIXME: Handle other kinds
+
+ Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps);
+
+ // TODO: may be better to pass function scope and not lookup it every
+ // time? find nearest parent function block
+ Block *cur = &block;
+ while (cur->GetParent()) {
+ cur = cur->GetParent();
+ }
+ PdbCompilandSymId func_scope_id =
+ PdbSymUid(cur->GetID()).asCompilandSym();
+ CVSymbol func_block_cvs = index.ReadSymbolRecord(func_scope_id);
+ lldbassert(func_block_cvs.kind() == S_GPROC32 ||
+ func_block_cvs.kind() == S_LPROC32);
+
+ PdbCompilandSymId frame_proc_id(
+ func_scope_id.modi, func_scope_id.offset + func_block_cvs.length());
+
+ bool is_parameter =
+ ((local.Flags & LocalSymFlags::IsParameter) != LocalSymFlags::None);
+ RegisterId base_reg =
+ GetBaseFrameRegister(index, frame_proc_id, is_parameter);
+
+ if (base_reg == RegisterId::VFRAME) {
+ llvm::StringRef program;
+ if (GetFrameDataProgram(index, ranges, program)) {
+ result.location =
+ MakeVFrameRelLocationExpression(program, loc.Offset, module);
+ result.ranges = std::move(ranges);
+ } else {
+ // invalid variable
+ }
+ } else {
+ result.location =
+ MakeRegRelLocationExpression(base_reg, loc.Offset, module);
+ result.ranges = std::move(ranges);
+ }
+ } else if (loc_specifier_cvs.kind() == S_DEFRANGE_REGISTER_REL) {
+ DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym);
+ cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>(
+ loc_specifier_cvs, loc));
+
+ Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps);
+
+ RegisterId base_reg = (RegisterId)(uint16_t)loc.Hdr.Register;
+
+ if (base_reg == RegisterId::VFRAME) {
+ llvm::StringRef program;
+ if (GetFrameDataProgram(index, ranges, program)) {
+ result.location = MakeVFrameRelLocationExpression(
+ program, loc.Hdr.BasePointerOffset, module);
+ result.ranges = std::move(ranges);
+ } else {
+ // invalid variable
+ }
+ } else {
+ result.location = MakeRegRelLocationExpression(
+ base_reg, loc.Hdr.BasePointerOffset, module);
+ result.ranges = std::move(ranges);
+ }
}
+
+ // FIXME: Handle other kinds
return result;
}
llvm_unreachable("Symbol is not a local variable!");
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
index 570c300b6a2b..6f675b56dca4 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
@@ -1,9 +1,8 @@
//===-- PdbUtil.h -----------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -142,7 +141,7 @@ LookThroughModifierRecord(llvm::codeview::CVType modifier);
llvm::StringRef DropNameScope(llvm::StringRef name);
VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol);
-VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id,
+VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, Block& block,
lldb::ModuleSP module);
size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 7e97e2b37724..e27d4699ae2f 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1,9 +1,8 @@
//===-- SymbolFileNativePDB.cpp ---------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -74,6 +73,8 @@ static lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
return lldb::LanguageType::eLanguageTypeC_plus_plus;
case PDB_Lang::C:
return lldb::LanguageType::eLanguageTypeC;
+ case PDB_Lang::Swift:
+ return lldb::LanguageType::eLanguageTypeSwift;
default:
return lldb::LanguageType::eLanguageTypeUnknown;
}
@@ -316,7 +317,7 @@ uint32_t SymbolFileNativePDB::CalculateAbilities() {
}
void SymbolFileNativePDB::InitializeObject() {
- m_obj_load_address = m_obj_file->GetFileOffset();
+ m_obj_load_address = m_obj_file->GetBaseAddress().GetFileAddress();
m_index->SetLoadAddress(m_obj_load_address);
m_index->ParseSectionContribs();
@@ -594,6 +595,17 @@ TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id,
return array_sp;
}
+
+TypeSP SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id,
+ const MemberFunctionRecord &mfr,
+ CompilerType ct) {
+ Declaration decl;
+ return std::make_shared<lldb_private::Type>(
+ toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID,
+ lldb_private::Type::eEncodingIsUID, decl, ct,
+ lldb_private::Type::eResolveStateFull);
+}
+
TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id,
const ProcedureRecord &pr,
CompilerType ct) {
@@ -654,6 +666,11 @@ TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) {
llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));
return CreateProcedureType(type_id, pr, ct);
}
+ if (cvt.kind() == LF_MFUNCTION) {
+ MemberFunctionRecord mfr;
+ llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));
+ return CreateFunctionType(type_id, mfr, ct);
+ }
return nullptr;
}
@@ -1137,7 +1154,7 @@ bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit,
}
bool SymbolFileNativePDB::ParseImportedModules(
- const SymbolContext &sc, std::vector<ConstString> &imported_modules) {
+ const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
// PDB does not yet support module debug info
return false;
}
@@ -1151,7 +1168,7 @@ size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); }
uint32_t SymbolFileNativePDB::FindGlobalVariables(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
@@ -1178,7 +1195,7 @@ uint32_t SymbolFileNativePDB::FindGlobalVariables(
}
uint32_t SymbolFileNativePDB::FindFunctions(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
FunctionNameType name_type_mask, bool include_inlines, bool append,
SymbolContextList &sc_list) {
// For now we only support lookup by method name.
@@ -1219,7 +1236,7 @@ uint32_t SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
}
uint32_t SymbolFileNativePDB::FindTypes(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
bool append, uint32_t max_matches,
llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
if (!append)
@@ -1316,7 +1333,9 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
PdbCompilandSymId var_id,
bool is_param) {
ModuleSP module = GetObjectFile()->GetModule();
- VariableInfo var_info = GetVariableLocationInfo(*m_index, var_id, module);
+ Block &block = GetOrCreateBlock(scope_id);
+ VariableInfo var_info =
+ GetVariableLocationInfo(*m_index, var_id, block, module);
if (!var_info.location || !var_info.ranges)
return nullptr;
@@ -1549,7 +1568,7 @@ size_t SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
}
CompilerDeclContext
-SymbolFileNativePDB::FindNamespace(const ConstString &name,
+SymbolFileNativePDB::FindNamespace(ConstString name,
const CompilerDeclContext *parent_decl_ctx) {
return {};
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index dcf3fe365ef1..20daff219a0a 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -1,9 +1,8 @@
//===-- SymbolFileNativePDB.h -----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -45,9 +44,7 @@ class SymbolFileNativePDB : public SymbolFile {
friend class UdtRecordCompleter;
public:
- //------------------------------------------------------------------
// Static Functions
- //------------------------------------------------------------------
static void Initialize();
static void Terminate();
@@ -60,9 +57,7 @@ public:
static SymbolFile *CreateInstance(ObjectFile *obj_file);
- //------------------------------------------------------------------
// Constructors and Destructors
- //------------------------------------------------------------------
SymbolFileNativePDB(ObjectFile *ofile);
~SymbolFileNativePDB() override;
@@ -71,9 +66,7 @@ public:
void InitializeObject() override;
- //------------------------------------------------------------------
// Compile Unit function calls
- //------------------------------------------------------------------
uint32_t GetNumCompileUnits() override;
@@ -95,13 +88,13 @@ public:
FileSpecList &support_files) override;
size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;
- bool
- ParseImportedModules(const SymbolContext &sc,
- std::vector<ConstString> &imported_modules) override;
+ bool ParseImportedModules(
+ const SymbolContext &sc,
+ std::vector<lldb_private::SourceModule> &imported_modules) override;
size_t ParseBlocksRecursive(Function &func) override;
- uint32_t FindGlobalVariables(const ConstString &name,
+ uint32_t FindGlobalVariables(ConstString name,
const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
VariableList &variables) override;
@@ -130,7 +123,7 @@ public:
size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
TypeList &type_list) override;
- uint32_t FindFunctions(const ConstString &name,
+ uint32_t FindFunctions(ConstString name,
const CompilerDeclContext *parent_decl_ctx,
lldb::FunctionNameType name_type_mask,
bool include_inlines, bool append,
@@ -139,7 +132,7 @@ public:
uint32_t FindFunctions(const RegularExpression &regex, bool include_inlines,
bool append, SymbolContextList &sc_list) override;
- uint32_t FindTypes(const ConstString &name,
+ uint32_t FindTypes(ConstString name,
const CompilerDeclContext *parent_decl_ctx, bool append,
uint32_t max_matches,
llvm::DenseSet<SymbolFile *> &searched_symbol_files,
@@ -151,7 +144,7 @@ public:
TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override;
CompilerDeclContext
- FindNamespace(const ConstString &name,
+ FindNamespace(ConstString name,
const CompilerDeclContext *parent_decl_ctx) override;
ConstString GetPluginName() override;
@@ -187,6 +180,9 @@ private:
lldb::TypeSP CreateArrayType(PdbTypeSymId type_id,
const llvm::codeview::ArrayRecord &ar,
CompilerType ct);
+ lldb::TypeSP CreateFunctionType(PdbTypeSymId type_id,
+ const llvm::codeview::MemberFunctionRecord &pr,
+ CompilerType ct);
lldb::TypeSP CreateProcedureType(PdbTypeSymId type_id,
const llvm::codeview::ProcedureRecord &pr,
CompilerType ct);
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
index 239dfbee625d..3c494dc83986 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -50,7 +50,8 @@ UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id,
}
clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex(
- llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access) {
+ llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access,
+ llvm::Optional<uint64_t> vtable_idx) {
PdbTypeSymId type_id(ti);
clang::QualType qt = m_ast_builder.GetOrCreateType(type_id);
@@ -58,13 +59,32 @@ clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex(
std::unique_ptr<clang::CXXBaseSpecifier> base_spec =
m_ast_builder.clang().CreateBaseClassSpecifier(
- qt.getAsOpaquePtr(), TranslateMemberAccess(access), false,
- udt_cvt.kind() == LF_CLASS);
+ qt.getAsOpaquePtr(), TranslateMemberAccess(access),
+ vtable_idx.hasValue(), udt_cvt.kind() == LF_CLASS);
lldbassert(base_spec);
- m_bases.push_back(std::move(base_spec));
+
+ m_bases.push_back(
+ std::make_pair(vtable_idx.getValueOr(0), std::move(base_spec)));
+
return qt;
}
+void UdtRecordCompleter::AddMethod(llvm::StringRef name, TypeIndex type_idx,
+ MemberAccess access, MethodOptions options,
+ MemberAttributes attrs) {
+ clang::QualType method_qt =
+ m_ast_builder.GetOrCreateType(PdbTypeSymId(type_idx));
+ m_ast_builder.CompleteType(method_qt);
+
+ lldb::AccessType access_type = TranslateMemberAccess(access);
+ bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
+ MethodOptions::CompilerGenerated;
+ m_ast_builder.clang().AddMethodToCXXRecordType(
+ m_derived_ct.GetOpaqueQualType(), name.data(), nullptr,
+ m_ast_builder.ToCompilerType(method_qt), access_type, attrs.isVirtual(),
+ attrs.isStatic(), false, false, false, is_artificial);
+}
+
Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
BaseClassRecord &base) {
clang::QualType base_qt =
@@ -82,9 +102,8 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
VirtualBaseClassRecord &base) {
- AddBaseClassForTypeIndex(base.BaseType, base.getAccess());
+ AddBaseClassForTypeIndex(base.BaseType, base.getAccess(), base.VTableIndex);
- // FIXME: Handle virtual base offsets.
return Error::success();
}
@@ -158,11 +177,27 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
OneMethodRecord &one_method) {
+ AddMethod(one_method.Name, one_method.Type, one_method.getAccess(),
+ one_method.getOptions(), one_method.Attrs);
+
return Error::success();
}
Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
OverloadedMethodRecord &overloaded) {
+ TypeIndex method_list_idx = overloaded.MethodList;
+
+ CVType method_list_type = m_tpi.getType(method_list_idx);
+ assert(method_list_type.kind() == LF_METHODLIST);
+
+ MethodOverloadListRecord method_list;
+ llvm::cantFail(TypeDeserializer::deserializeAs<MethodOverloadListRecord>(
+ method_list_type, method_list));
+
+ for (const OneMethodRecord &method : method_list.Methods)
+ AddMethod(overloaded.Name, method.Type, method.getAccess(),
+ method.getOptions(), method.Attrs);
+
return Error::success();
}
@@ -177,9 +212,19 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
}
void UdtRecordCompleter::complete() {
+ // Ensure the correct order for virtual bases.
+ std::stable_sort(m_bases.begin(), m_bases.end(),
+ [](const IndexedBase &lhs, const IndexedBase &rhs) {
+ return lhs.first < rhs.first;
+ });
+
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
+ bases.reserve(m_bases.size());
+ for (auto &ib : m_bases)
+ bases.push_back(std::move(ib.second));
+
ClangASTContext &clang = m_ast_builder.clang();
- clang.TransferBaseClasses(m_derived_ct.GetOpaqueQualType(),
- std::move(m_bases));
+ clang.TransferBaseClasses(m_derived_ct.GetOpaqueQualType(), std::move(bases));
clang.AddMethodOverridesForCXXRecordType(m_derived_ct.GetOpaqueQualType());
ClangASTContext::BuildIndirectFields(m_derived_ct);
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
index 469685126e59..55397582209b 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
@@ -1,9 +1,8 @@
-//===-- SymbolFileNativePDB.h -----------------------------------*- C++ -*-===//
+//===-- UdtRecordCompleter.h ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -36,6 +35,9 @@ namespace npdb {
class PdbAstBuilder;
class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks {
+ using IndexedBase =
+ std::pair<uint64_t, std::unique_ptr<clang::CXXBaseSpecifier>>;
+
union UdtTagRecord {
UdtTagRecord() {}
llvm::codeview::UnionRecord ur;
@@ -48,7 +50,7 @@ class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks {
clang::TagDecl &m_tag_decl;
PdbAstBuilder &m_ast_builder;
llvm::pdb::TpiStream &m_tpi;
- std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> m_bases;
+ std::vector<IndexedBase> m_bases;
ClangASTImporter::LayoutInfo m_layout;
public:
@@ -65,8 +67,13 @@ public:
void complete();
private:
- clang::QualType AddBaseClassForTypeIndex(llvm::codeview::TypeIndex ti,
- llvm::codeview::MemberAccess access);
+ clang::QualType AddBaseClassForTypeIndex(
+ llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access,
+ llvm::Optional<uint64_t> vtable_idx = llvm::Optional<uint64_t>());
+ void AddMethod(llvm::StringRef name, llvm::codeview::TypeIndex type_idx,
+ llvm::codeview::MemberAccess access,
+ llvm::codeview::MethodOptions options,
+ llvm::codeview::MemberAttributes attrs);
};
} // namespace npdb
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index 65e718bedaf1..82cfcfbb040f 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -1,9 +1,8 @@
//===-- PDBASTParser.cpp ----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -568,9 +567,12 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
ast_typedef = ast_typedef.AddVolatileModifier();
GetDeclarationForSymbol(type, decl);
+ llvm::Optional<uint64_t> size;
+ if (type_def->getLength())
+ size = type_def->getLength();
return std::make_shared<lldb_private::Type>(
type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
- type_def->getLength(), nullptr, target_type->GetID(),
+ size, nullptr, target_type->GetID(),
lldb_private::Type::eEncodingIsTypedefUID, decl, ast_typedef,
lldb_private::Type::eResolveStateFull);
} break;
@@ -637,16 +639,19 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
GetDeclarationForSymbol(type, decl);
return std::make_shared<lldb_private::Type>(
- type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), 0,
- nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
- func_sig_ast_type, lldb_private::Type::eResolveStateFull);
+ type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
+ llvm::None, nullptr, LLDB_INVALID_UID,
+ lldb_private::Type::eEncodingIsUID, decl, func_sig_ast_type,
+ lldb_private::Type::eResolveStateFull);
} break;
case PDB_SymType::ArrayType: {
auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type);
assert(array_type);
uint32_t num_elements = array_type->getCount();
uint32_t element_uid = array_type->getElementTypeId();
- uint32_t bytes = array_type->getLength();
+ llvm::Optional<uint64_t> bytes;
+ if (uint64_t size = array_type->getLength())
+ bytes = size;
// If array rank > 0, PDB gives the element type at N=0. So element type
// will parsed in the order N=0, N=1,..., N=rank sequentially.
@@ -682,10 +687,12 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
if (builtin_kind == PDB_BuiltinType::None)
return nullptr;
- uint64_t bytes = builtin_type->getLength();
+ llvm::Optional<uint64_t> bytes;
+ if (uint64_t size = builtin_type->getLength())
+ bytes = size;
Encoding encoding = TranslateBuiltinEncoding(builtin_kind);
CompilerType builtin_ast_type = GetBuiltinTypeForPDBEncodingAndBitSize(
- m_ast, *builtin_type, encoding, bytes * 8);
+ m_ast, *builtin_type, encoding, bytes.getValueOr(0) * 8);
if (builtin_type->isConstType())
builtin_ast_type = builtin_ast_type.AddConstModifier();
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h
index 02353870ab60..9221d42b2020 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h
@@ -1,9 +1,8 @@
//===-- PDBASTParser.h ------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
index 9f398ef9b047..1c17bf6563b3 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
@@ -1,9 +1,8 @@
//===-- PDBLocationToDWARFExpression.cpp ------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -13,487 +12,64 @@
#include "lldb/Core/StreamBuffer.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Symbol/Variable.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
-#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+#include "Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h"
+#include "Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h"
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::npdb;
using namespace llvm::pdb;
-namespace {
-const uint32_t g_code_view_to_lldb_registers_x86[] = {
- LLDB_INVALID_REGNUM, // NONE
- lldb_al_i386, // AL
- lldb_cl_i386, // CL
- lldb_dl_i386, // DL
- lldb_bl_i386, // BL
- lldb_ah_i386, // AH
- lldb_ch_i386, // CH
- lldb_dh_i386, // DH
- lldb_bh_i386, // BH
- lldb_ax_i386, // AX
- lldb_cx_i386, // CX
- lldb_dx_i386, // DX
- lldb_bx_i386, // BX
- lldb_sp_i386, // SP
- lldb_bp_i386, // BP
- lldb_si_i386, // SI
- lldb_di_i386, // DI
- lldb_eax_i386, // EAX
- lldb_ecx_i386, // ECX
- lldb_edx_i386, // EDX
- lldb_ebx_i386, // EBX
- lldb_esp_i386, // ESP
- lldb_ebp_i386, // EBP
- lldb_esi_i386, // ESI
- lldb_edi_i386, // EDI
- lldb_es_i386, // ES
- lldb_cs_i386, // CS
- lldb_ss_i386, // SS
- lldb_ds_i386, // DS
- lldb_fs_i386, // FS
- lldb_gs_i386, // GS
- LLDB_INVALID_REGNUM, // IP
- LLDB_INVALID_REGNUM, // FLAGS
- lldb_eip_i386, // EIP
- lldb_eflags_i386, // EFLAGS
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // TEMP
- LLDB_INVALID_REGNUM, // TEMPH
- LLDB_INVALID_REGNUM, // QUOTE
- LLDB_INVALID_REGNUM, // PCDR3
- LLDB_INVALID_REGNUM, // PCDR4
- LLDB_INVALID_REGNUM, // PCDR5
- LLDB_INVALID_REGNUM, // PCDR6
- LLDB_INVALID_REGNUM, // PCDR7
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // CR0
- LLDB_INVALID_REGNUM, // CR1
- LLDB_INVALID_REGNUM, // CR2
- LLDB_INVALID_REGNUM, // CR3
- LLDB_INVALID_REGNUM, // CR4
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_dr0_i386, // DR0
- lldb_dr1_i386, // DR1
- lldb_dr2_i386, // DR2
- lldb_dr3_i386, // DR3
- lldb_dr4_i386, // DR4
- lldb_dr5_i386, // DR5
- lldb_dr6_i386, // DR6
- lldb_dr7_i386, // DR7
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // GDTR
- LLDB_INVALID_REGNUM, // GDTL
- LLDB_INVALID_REGNUM, // IDTR
- LLDB_INVALID_REGNUM, // IDTL
- LLDB_INVALID_REGNUM, // LDTR
- LLDB_INVALID_REGNUM, // TR
- LLDB_INVALID_REGNUM, // PSEUDO1
- LLDB_INVALID_REGNUM, // PSEUDO2
- LLDB_INVALID_REGNUM, // PSEUDO3
- LLDB_INVALID_REGNUM, // PSEUDO4
- LLDB_INVALID_REGNUM, // PSEUDO5
- LLDB_INVALID_REGNUM, // PSEUDO6
- LLDB_INVALID_REGNUM, // PSEUDO7
- LLDB_INVALID_REGNUM, // PSEUDO8
- LLDB_INVALID_REGNUM, // PSEUDO9
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_st0_i386, // ST0
- lldb_st1_i386, // ST1
- lldb_st2_i386, // ST2
- lldb_st3_i386, // ST3
- lldb_st4_i386, // ST4
- lldb_st5_i386, // ST5
- lldb_st6_i386, // ST6
- lldb_st7_i386, // ST7
- LLDB_INVALID_REGNUM, // CTRL
- LLDB_INVALID_REGNUM, // STAT
- LLDB_INVALID_REGNUM, // TAG
- LLDB_INVALID_REGNUM, // FPIP
- LLDB_INVALID_REGNUM, // FPCS
- LLDB_INVALID_REGNUM, // FPDO
- LLDB_INVALID_REGNUM, // FPDS
- LLDB_INVALID_REGNUM, // ISEM
- LLDB_INVALID_REGNUM, // FPEIP
- LLDB_INVALID_REGNUM, // FPEDO
- lldb_mm0_i386, // MM0
- lldb_mm1_i386, // MM1
- lldb_mm2_i386, // MM2
- lldb_mm3_i386, // MM3
- lldb_mm4_i386, // MM4
- lldb_mm5_i386, // MM5
- lldb_mm6_i386, // MM6
- lldb_mm7_i386, // MM7
- lldb_xmm0_i386, // XMM0
- lldb_xmm1_i386, // XMM1
- lldb_xmm2_i386, // XMM2
- lldb_xmm3_i386, // XMM3
- lldb_xmm4_i386, // XMM4
- lldb_xmm5_i386, // XMM5
- lldb_xmm6_i386, // XMM6
- lldb_xmm7_i386 // XMM7
-};
-
-const uint32_t g_code_view_to_lldb_registers_x86_64[] = {
- LLDB_INVALID_REGNUM, // NONE
- lldb_al_x86_64, // AL
- lldb_cl_x86_64, // CL
- lldb_dl_x86_64, // DL
- lldb_bl_x86_64, // BL
- lldb_ah_x86_64, // AH
- lldb_ch_x86_64, // CH
- lldb_dh_x86_64, // DH
- lldb_bh_x86_64, // BH
- lldb_ax_x86_64, // AX
- lldb_cx_x86_64, // CX
- lldb_dx_x86_64, // DX
- lldb_bx_x86_64, // BX
- lldb_sp_x86_64, // SP
- lldb_bp_x86_64, // BP
- lldb_si_x86_64, // SI
- lldb_di_x86_64, // DI
- lldb_eax_x86_64, // EAX
- lldb_ecx_x86_64, // ECX
- lldb_edx_x86_64, // EDX
- lldb_ebx_x86_64, // EBX
- lldb_esp_x86_64, // ESP
- lldb_ebp_x86_64, // EBP
- lldb_esi_x86_64, // ESI
- lldb_edi_x86_64, // EDI
- lldb_es_x86_64, // ES
- lldb_cs_x86_64, // CS
- lldb_ss_x86_64, // SS
- lldb_ds_x86_64, // DS
- lldb_fs_x86_64, // FS
- lldb_gs_x86_64, // GS
- LLDB_INVALID_REGNUM, // IP
- LLDB_INVALID_REGNUM, // FLAGS
- LLDB_INVALID_REGNUM, // EIP
- LLDB_INVALID_REGNUM, // EFLAGS
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // TEMP
- LLDB_INVALID_REGNUM, // TEMPH
- LLDB_INVALID_REGNUM, // QUOTE
- LLDB_INVALID_REGNUM, // PCDR3
- LLDB_INVALID_REGNUM, // PCDR4
- LLDB_INVALID_REGNUM, // PCDR5
- LLDB_INVALID_REGNUM, // PCDR6
- LLDB_INVALID_REGNUM, // PCDR7
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // CR0
- LLDB_INVALID_REGNUM, // CR1
- LLDB_INVALID_REGNUM, // CR2
- LLDB_INVALID_REGNUM, // CR3
- LLDB_INVALID_REGNUM, // CR4
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_dr0_x86_64, // DR0
- lldb_dr1_x86_64, // DR1
- lldb_dr2_x86_64, // DR2
- lldb_dr3_x86_64, // DR3
- lldb_dr4_x86_64, // DR4
- lldb_dr5_x86_64, // DR5
- lldb_dr6_x86_64, // DR6
- lldb_dr7_x86_64, // DR7
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // GDTR
- LLDB_INVALID_REGNUM, // GDTL
- LLDB_INVALID_REGNUM, // IDTR
- LLDB_INVALID_REGNUM, // IDTL
- LLDB_INVALID_REGNUM, // LDTR
- LLDB_INVALID_REGNUM, // TR
- LLDB_INVALID_REGNUM, // PSEUDO1
- LLDB_INVALID_REGNUM, // PSEUDO2
- LLDB_INVALID_REGNUM, // PSEUDO3
- LLDB_INVALID_REGNUM, // PSEUDO4
- LLDB_INVALID_REGNUM, // PSEUDO5
- LLDB_INVALID_REGNUM, // PSEUDO6
- LLDB_INVALID_REGNUM, // PSEUDO7
- LLDB_INVALID_REGNUM, // PSEUDO8
- LLDB_INVALID_REGNUM, // PSEUDO9
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_st0_x86_64, // ST0
- lldb_st1_x86_64, // ST1
- lldb_st2_x86_64, // ST2
- lldb_st3_x86_64, // ST3
- lldb_st4_x86_64, // ST4
- lldb_st5_x86_64, // ST5
- lldb_st6_x86_64, // ST6
- lldb_st7_x86_64, // ST7
- LLDB_INVALID_REGNUM, // CTRL
- LLDB_INVALID_REGNUM, // STAT
- LLDB_INVALID_REGNUM, // TAG
- LLDB_INVALID_REGNUM, // FPIP
- LLDB_INVALID_REGNUM, // FPCS
- LLDB_INVALID_REGNUM, // FPDO
- LLDB_INVALID_REGNUM, // FPDS
- LLDB_INVALID_REGNUM, // ISEM
- LLDB_INVALID_REGNUM, // FPEIP
- LLDB_INVALID_REGNUM, // FPEDO
- lldb_mm0_x86_64, // MM0
- lldb_mm1_x86_64, // MM1
- lldb_mm2_x86_64, // MM2
- lldb_mm3_x86_64, // MM3
- lldb_mm4_x86_64, // MM4
- lldb_mm5_x86_64, // MM5
- lldb_mm6_x86_64, // MM6
- lldb_mm7_x86_64, // MM7
- lldb_xmm0_x86_64, // XMM0
- lldb_xmm1_x86_64, // XMM1
- lldb_xmm2_x86_64, // XMM2
- lldb_xmm3_x86_64, // XMM3
- lldb_xmm4_x86_64, // XMM4
- lldb_xmm5_x86_64, // XMM5
- lldb_xmm6_x86_64, // XMM6
- lldb_xmm7_x86_64, // XMM7
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM,
- lldb_mxcsr_x86_64, // MXCSR
- LLDB_INVALID_REGNUM, // EDXEAX
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // EMM0L
- LLDB_INVALID_REGNUM, // EMM1L
- LLDB_INVALID_REGNUM, // EMM2L
- LLDB_INVALID_REGNUM, // EMM3L
- LLDB_INVALID_REGNUM, // EMM4L
- LLDB_INVALID_REGNUM, // EMM5L
- LLDB_INVALID_REGNUM, // EMM6L
- LLDB_INVALID_REGNUM, // EMM7L
- LLDB_INVALID_REGNUM, // EMM0H
- LLDB_INVALID_REGNUM, // EMM1H
- LLDB_INVALID_REGNUM, // EMM2H
- LLDB_INVALID_REGNUM, // EMM3H
- LLDB_INVALID_REGNUM, // EMM4H
- LLDB_INVALID_REGNUM, // EMM5H
- LLDB_INVALID_REGNUM, // EMM6H
- LLDB_INVALID_REGNUM, // EMM7H
- LLDB_INVALID_REGNUM, // MM00
- LLDB_INVALID_REGNUM, // MM01
- LLDB_INVALID_REGNUM, // MM10
- LLDB_INVALID_REGNUM, // MM11
- LLDB_INVALID_REGNUM, // MM20
- LLDB_INVALID_REGNUM, // MM21
- LLDB_INVALID_REGNUM, // MM30
- LLDB_INVALID_REGNUM, // MM31
- LLDB_INVALID_REGNUM, // MM40
- LLDB_INVALID_REGNUM, // MM41
- LLDB_INVALID_REGNUM, // MM50
- LLDB_INVALID_REGNUM, // MM51
- LLDB_INVALID_REGNUM, // MM60
- LLDB_INVALID_REGNUM, // MM61
- LLDB_INVALID_REGNUM, // MM70
- LLDB_INVALID_REGNUM, // MM71
- lldb_xmm8_x86_64, // XMM8
- lldb_xmm9_x86_64, // XMM9
- lldb_xmm10_x86_64, // XMM10
- lldb_xmm11_x86_64, // XMM11
- lldb_xmm12_x86_64, // XMM12
- lldb_xmm13_x86_64, // XMM13
- lldb_xmm14_x86_64, // XMM14
- lldb_xmm15_x86_64, // XMM15
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM,
- lldb_sil_x86_64, // SIL
- lldb_dil_x86_64, // DIL
- lldb_bpl_x86_64, // BPL
- lldb_spl_x86_64, // SPL
- lldb_rax_x86_64, // RAX
- lldb_rbx_x86_64, // RBX
- lldb_rcx_x86_64, // RCX
- lldb_rdx_x86_64, // RDX
- lldb_rsi_x86_64, // RSI
- lldb_rdi_x86_64, // RDI
- lldb_rbp_x86_64, // RBP
- lldb_rsp_x86_64, // RSP
- lldb_r8_x86_64, // R8
- lldb_r9_x86_64, // R9
- lldb_r10_x86_64, // R10
- lldb_r11_x86_64, // R11
- lldb_r12_x86_64, // R12
- lldb_r13_x86_64, // R13
- lldb_r14_x86_64, // R14
- lldb_r15_x86_64, // R15
- lldb_r8l_x86_64, // R8B
- lldb_r9l_x86_64, // R9B
- lldb_r10l_x86_64, // R10B
- lldb_r11l_x86_64, // R11B
- lldb_r12l_x86_64, // R12B
- lldb_r13l_x86_64, // R13B
- lldb_r14l_x86_64, // R14B
- lldb_r15l_x86_64, // R15B
- lldb_r8w_x86_64, // R8W
- lldb_r9w_x86_64, // R9W
- lldb_r10w_x86_64, // R10W
- lldb_r11w_x86_64, // R11W
- lldb_r12w_x86_64, // R12W
- lldb_r13w_x86_64, // R13W
- lldb_r14w_x86_64, // R14W
- lldb_r15w_x86_64, // R15W
- lldb_r8d_x86_64, // R8D
- lldb_r9d_x86_64, // R9D
- lldb_r10d_x86_64, // R10D
- lldb_r11d_x86_64, // R11D
- lldb_r12d_x86_64, // R12D
- lldb_r13d_x86_64, // R13D
- lldb_r14d_x86_64, // R14D
- lldb_r15d_x86_64, // R15D
- lldb_ymm0_x86_64, // AMD64_YMM0
- lldb_ymm1_x86_64, // AMD64_YMM1
- lldb_ymm2_x86_64, // AMD64_YMM2
- lldb_ymm3_x86_64, // AMD64_YMM3
- lldb_ymm4_x86_64, // AMD64_YMM4
- lldb_ymm5_x86_64, // AMD64_YMM5
- lldb_ymm6_x86_64, // AMD64_YMM6
- lldb_ymm7_x86_64, // AMD64_YMM7
- lldb_ymm8_x86_64, // AMD64_YMM8
- lldb_ymm9_x86_64, // AMD64_YMM9
- lldb_ymm10_x86_64, // AMD64_YMM10
- lldb_ymm11_x86_64, // AMD64_YMM11
- lldb_ymm12_x86_64, // AMD64_YMM12
- lldb_ymm13_x86_64, // AMD64_YMM13
- lldb_ymm14_x86_64, // AMD64_YMM14
- lldb_ymm15_x86_64, // AMD64_YMM15
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_bnd0_x86_64, // BND0
- lldb_bnd1_x86_64, // BND1
- lldb_bnd2_x86_64 // BND2
-};
-
-uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type,
- llvm::codeview::RegisterId register_id) {
- switch (arch_type) {
- case llvm::Triple::x86:
- if (static_cast<uint16_t>(register_id) <
- sizeof(g_code_view_to_lldb_registers_x86) /
- sizeof(g_code_view_to_lldb_registers_x86[0]))
- return g_code_view_to_lldb_registers_x86[static_cast<uint16_t>(
- register_id)];
-
- switch (register_id) {
- case llvm::codeview::RegisterId::MXCSR:
- return lldb_mxcsr_i386;
- case llvm::codeview::RegisterId::BND0:
- return lldb_bnd0_i386;
- case llvm::codeview::RegisterId::BND1:
- return lldb_bnd1_i386;
- case llvm::codeview::RegisterId::BND2:
- return lldb_bnd2_i386;
- default:
- return LLDB_INVALID_REGNUM;
+static std::unique_ptr<IPDBFrameData>
+GetCorrespondingFrameData(const IPDBSession &session,
+ const Variable::RangeList &ranges) {
+ auto enumFrameData = session.getFrameData();
+ if (!enumFrameData)
+ return nullptr;
+
+ std::unique_ptr<IPDBFrameData> found;
+ while (auto fd = enumFrameData->getNext()) {
+ Range<lldb::addr_t, lldb::addr_t> fdRange(fd->getVirtualAddress(),
+ fd->getLengthBlock());
+
+ for (size_t i = 0; i < ranges.GetSize(); i++) {
+ auto range = ranges.GetEntryAtIndex(i);
+ if (!range)
+ continue;
+
+ if (!range->DoesIntersect(fdRange))
+ continue;
+
+ found = std::move(fd);
+
+ break;
}
- case llvm::Triple::x86_64:
- if (static_cast<uint16_t>(register_id) <
- sizeof(g_code_view_to_lldb_registers_x86_64) /
- sizeof(g_code_view_to_lldb_registers_x86_64[0]))
- return g_code_view_to_lldb_registers_x86_64[static_cast<uint16_t>(
- register_id)];
-
- return LLDB_INVALID_REGNUM;
- default:
- return LLDB_INVALID_REGNUM;
}
-}
-
-uint32_t GetGenericRegisterNumber(llvm::codeview::RegisterId register_id) {
- if (register_id == llvm::codeview::RegisterId::VFRAME)
- return LLDB_REGNUM_GENERIC_FP;
- return LLDB_INVALID_REGNUM;
+ return found;
}
-uint32_t GetRegisterNumber(llvm::Triple::ArchType arch_type,
- llvm::codeview::RegisterId register_id,
- RegisterKind &register_kind) {
- register_kind = eRegisterKindLLDB;
- uint32_t reg_num = GetLLDBRegisterNumber(arch_type, register_id);
- if (reg_num != LLDB_INVALID_REGNUM)
- return reg_num;
-
- register_kind = eRegisterKindGeneric;
- return GetGenericRegisterNumber(register_id);
+static bool EmitVFrameEvaluationDWARFExpression(
+ llvm::StringRef program, llvm::Triple::ArchType arch_type, Stream &stream) {
+ // VFrame value always stored in $TO pseudo-register
+ return TranslateFPOProgramToDWARFExpression(program, "$T0", arch_type,
+ stream);
}
-} // namespace
-DWARFExpression ConvertPDBLocationToDWARFExpression(ModuleSP module,
- const PDBSymbolData &symbol,
- bool &is_constant) {
+DWARFExpression ConvertPDBLocationToDWARFExpression(
+ ModuleSP module, const PDBSymbolData &symbol,
+ const Variable::RangeList &ranges, bool &is_constant) {
is_constant = true;
if (!module)
- return DWARFExpression(nullptr);
+ return DWARFExpression();
const ArchSpec &architecture = module->GetArchitecture();
llvm::Triple::ArchType arch_type = architecture.GetMachine();
@@ -501,7 +77,7 @@ DWARFExpression ConvertPDBLocationToDWARFExpression(ModuleSP module,
uint32_t address_size = architecture.GetAddressByteSize();
uint32_t byte_size = architecture.GetDataByteSize();
if (byte_order == eByteOrderInvalid || address_size == 0)
- return DWARFExpression(nullptr);
+ return DWARFExpression();
RegisterKind register_kind = eRegisterKindDWARF;
StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
@@ -512,15 +88,13 @@ DWARFExpression ConvertPDBLocationToDWARFExpression(ModuleSP module,
SectionList *section_list = module->GetSectionList();
if (!section_list)
- return DWARFExpression(nullptr);
+ return DWARFExpression();
- uint32_t section_idx = symbol.getAddressSection() - 1;
- if (section_idx >= section_list->GetSize())
- return DWARFExpression(nullptr);
+ uint32_t section_id = symbol.getAddressSection();
- auto section = section_list->GetSectionAtIndex(section_idx);
+ auto section = section_list->FindSectionByID(section_id);
if (!section)
- return DWARFExpression(nullptr);
+ return DWARFExpression();
uint32_t offset = symbol.getAddressOffset();
stream.PutMaxHex64(section->GetFileAddress() + offset, address_size,
@@ -531,10 +105,32 @@ DWARFExpression ConvertPDBLocationToDWARFExpression(ModuleSP module,
break;
}
case PDB_LocType::RegRel: {
- uint32_t reg_num =
- GetRegisterNumber(arch_type, symbol.getRegisterId(), register_kind);
- if (reg_num == LLDB_INVALID_REGNUM)
- return DWARFExpression(nullptr);
+ uint32_t reg_num;
+ auto reg_id = symbol.getRegisterId();
+ if (reg_id == llvm::codeview::RegisterId::VFRAME) {
+ if (auto fd = GetCorrespondingFrameData(symbol.getSession(), ranges)) {
+ if (EmitVFrameEvaluationDWARFExpression(fd->getProgram(), arch_type,
+ stream)) {
+ int32_t offset = symbol.getOffset();
+ stream.PutHex8(DW_OP_consts);
+ stream.PutSLEB128(offset);
+ stream.PutHex8(DW_OP_plus);
+
+ register_kind = eRegisterKindLLDB;
+
+ is_constant = false;
+ break;
+ }
+ }
+
+ register_kind = eRegisterKindGeneric;
+ reg_num = LLDB_REGNUM_GENERIC_FP;
+ } else {
+ register_kind = eRegisterKindLLDB;
+ reg_num = GetLLDBRegisterNumber(arch_type, reg_id);
+ if (reg_num == LLDB_INVALID_REGNUM)
+ return DWARFExpression();
+ }
if (reg_num > 31) {
stream.PutHex8(DW_OP_bregx);
@@ -550,10 +146,10 @@ DWARFExpression ConvertPDBLocationToDWARFExpression(ModuleSP module,
break;
}
case PDB_LocType::Enregistered: {
- uint32_t reg_num =
- GetRegisterNumber(arch_type, symbol.getRegisterId(), register_kind);
+ register_kind = eRegisterKindLLDB;
+ uint32_t reg_num = GetLLDBRegisterNumber(arch_type, symbol.getRegisterId());
if (reg_num == LLDB_INVALID_REGNUM)
- return DWARFExpression(nullptr);
+ return DWARFExpression();
if (reg_num > 31) {
stream.PutHex8(DW_OP_regx);
@@ -572,7 +168,7 @@ DWARFExpression ConvertPDBLocationToDWARFExpression(ModuleSP module,
break;
}
default:
- return DWARFExpression(nullptr);
+ return DWARFExpression();
}
DataBufferSP buffer =
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h
index 37b80dfccb84..2e9d1386d537 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h
@@ -1,9 +1,8 @@
//===-- PDBLocationToDWARFExpression.h --------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,6 +10,7 @@
#define lldb_Plugins_SymbolFile_PDB_PDBLocationToDWARFExpression_h_
#include "lldb/Core/Module.h"
+#include "lldb/Symbol/Variable.h"
namespace lldb_private {
class DWARFExpression;
@@ -22,24 +22,26 @@ class PDBSymbolData;
}
} // namespace llvm
-//------------------------------------------------------------------------------
/// Converts a location information from a PDB symbol to a DWARF expression
///
-/// @param[in] module
+/// \param[in] module
/// The module \a symbol belongs to.
///
-/// @param[in] symbol
+/// \param[in] symbol
/// The symbol with a location information to convert.
///
-/// @param[out] is_constant
+/// \param[in] ranges
+/// Ranges where this variable is valid.
+///
+/// \param[out] is_constant
/// Set to \b true if the result expression is a constant value data,
/// and \b false if it is a DWARF bytecode.
///
-/// @return
+/// \return
/// The DWARF expression corresponding to the location data of \a symbol.
-//------------------------------------------------------------------------------
lldb_private::DWARFExpression
ConvertPDBLocationToDWARFExpression(lldb::ModuleSP module,
const llvm::pdb::PDBSymbolData &symbol,
+ const lldb_private::Variable::RangeList &ranges,
bool &is_constant);
#endif
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index ad25842f4d05..17dfcdaceb9c 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1,9 +1,8 @@
//===-- SymbolFilePDB.cpp ---------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -65,6 +64,8 @@ lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
return lldb::LanguageType::eLanguageTypeC_plus_plus;
case PDB_Lang::C:
return lldb::LanguageType::eLanguageTypeC;
+ case PDB_Lang::Swift:
+ return lldb::LanguageType::eLanguageTypeSwift;
default:
return lldb::LanguageType::eLanguageTypeUnknown;
}
@@ -123,7 +124,7 @@ SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) {
SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
: SymbolFile(object_file), m_session_up(), m_global_scope_up(),
- m_cached_compile_unit_count(0), m_tu_decl_ctx_up() {}
+ m_cached_compile_unit_count(0) {}
SymbolFilePDB::~SymbolFilePDB() {}
@@ -182,20 +183,12 @@ uint32_t SymbolFilePDB::CalculateAbilities() {
}
void SymbolFilePDB::InitializeObject() {
- lldb::addr_t obj_load_address = m_obj_file->GetFileOffset();
+ lldb::addr_t obj_load_address = m_obj_file->GetBaseAddress().GetFileAddress();
lldbassert(obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS);
m_session_up->setLoadAddress(obj_load_address);
if (!m_global_scope_up)
m_global_scope_up = m_session_up->getGlobalScope();
lldbassert(m_global_scope_up.get());
-
- TypeSystem *type_system =
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- ClangASTContext *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(type_system);
- lldbassert(clang_type_system);
- m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(
- type_system, clang_type_system->GetTranslationUnitDecl());
}
uint32_t SymbolFilePDB::GetNumCompileUnits() {
@@ -308,7 +301,8 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
comp_unit.AddFunction(func_sp);
- TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ LanguageType lang = ParseLanguage(comp_unit);
+ TypeSystem *type_system = GetTypeSystemForLanguage(lang);
if (!type_system)
return nullptr;
ClangASTContext *clang_type_system =
@@ -378,7 +372,7 @@ bool SymbolFilePDB::ParseSupportFiles(
bool SymbolFilePDB::ParseImportedModules(
const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) {
+ std::vector<SourceModule> &imported_modules) {
// PDB does not yet support module debug info
return false;
}
@@ -934,12 +928,25 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData(
Variable::RangeList ranges;
SymbolContextScope *context_scope = sc.comp_unit;
- if (scope == eValueTypeVariableLocal) {
+ if (scope == eValueTypeVariableLocal || scope == eValueTypeVariableArgument) {
if (sc.function) {
- context_scope = sc.function->GetBlock(true).FindBlockByID(
- pdb_data.getLexicalParentId());
- if (context_scope == nullptr)
- context_scope = sc.function;
+ Block &function_block = sc.function->GetBlock(true);
+ Block *block =
+ function_block.FindBlockByID(pdb_data.getLexicalParentId());
+ if (!block)
+ block = &function_block;
+
+ context_scope = block;
+
+ for (size_t i = 0, num_ranges = block->GetNumRanges(); i < num_ranges;
+ ++i) {
+ AddressRange range;
+ if (!block->GetRangeAtIndex(i, range))
+ continue;
+
+ ranges.Append(range.GetBaseAddress().GetFileAddress(),
+ range.GetByteSize());
+ }
}
}
@@ -952,7 +959,7 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData(
bool is_constant;
DWARFExpression location = ConvertPDBLocationToDWARFExpression(
- GetObjectFile()->GetModule(), pdb_data, is_constant);
+ GetObjectFile()->GetModule(), pdb_data, ranges, is_constant);
var_sp = std::make_shared<Variable>(
var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope,
@@ -1034,7 +1041,7 @@ SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc,
}
uint32_t SymbolFilePDB::FindGlobalVariables(
- const lldb_private::ConstString &name,
+ lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, lldb_private::VariableList &variables) {
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
@@ -1234,7 +1241,7 @@ void SymbolFilePDB::CacheFunctionNames() {
}
uint32_t SymbolFilePDB::FindFunctions(
- const lldb_private::ConstString &name,
+ lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
FunctionNameType name_type_mask, bool include_inlines, bool append,
lldb_private::SymbolContextList &sc_list) {
@@ -1337,11 +1344,9 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
return;
while (auto pub_symbol = results->getNext()) {
- auto section_idx = pub_symbol->getAddressSection() - 1;
- if (section_idx >= section_list->GetSize())
- continue;
+ auto section_id = pub_symbol->getAddressSection();
- auto section = section_list->GetSectionAtIndex(section_idx);
+ auto section = section_list->FindSectionByID(section_id);
if (!section)
continue;
@@ -1376,7 +1381,7 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
}
uint32_t SymbolFilePDB::FindTypes(
- const lldb_private::ConstString &name,
+ lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
@@ -1618,7 +1623,7 @@ PDBASTParser *SymbolFilePDB::GetPDBAstParser() {
lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
- const lldb_private::ConstString &name,
+ lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) {
auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index 81288093b7d8..ba3099aaec4d 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -1,9 +1,8 @@
//===-- SymbolFilePDB.h -------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -24,9 +23,7 @@ class PDBASTParser;
class SymbolFilePDB : public lldb_private::SymbolFile {
public:
- //------------------------------------------------------------------
// Static Functions
- //------------------------------------------------------------------
static void Initialize();
static void Terminate();
@@ -40,9 +37,7 @@ public:
static lldb_private::SymbolFile *
CreateInstance(lldb_private::ObjectFile *obj_file);
- //------------------------------------------------------------------
// Constructors and Destructors
- //------------------------------------------------------------------
SymbolFilePDB(lldb_private::ObjectFile *ofile);
~SymbolFilePDB() override;
@@ -51,9 +46,7 @@ public:
void InitializeObject() override;
- //------------------------------------------------------------------
// Compile Unit function calls
- //------------------------------------------------------------------
uint32_t GetNumCompileUnits() override;
@@ -75,7 +68,7 @@ public:
bool ParseImportedModules(
const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) override;
+ std::vector<lldb_private::SourceModule> &imported_modules) override;
size_t ParseBlocksRecursive(lldb_private::Function &func) override;
@@ -111,7 +104,7 @@ public:
lldb_private::SymbolContextList &sc_list) override;
uint32_t
- FindGlobalVariables(const lldb_private::ConstString &name,
+ FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
@@ -121,7 +114,7 @@ public:
lldb_private::VariableList &variables) override;
uint32_t
- FindFunctions(const lldb_private::ConstString &name,
+ FindFunctions(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
lldb::FunctionNameType name_type_mask, bool include_inlines,
bool append, lldb_private::SymbolContextList &sc_list) override;
@@ -137,7 +130,7 @@ public:
void AddSymbols(lldb_private::Symtab &symtab) override;
uint32_t
- FindTypes(const lldb_private::ConstString &name,
+ FindTypes(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
bool append, uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
@@ -159,7 +152,7 @@ public:
GetTypeSystemForLanguage(lldb::LanguageType language) override;
lldb_private::CompilerDeclContext FindNamespace(
- const lldb_private::ConstString &name,
+ lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
lldb_private::ConstString GetPluginName() override;
@@ -253,7 +246,6 @@ private:
std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
std::unique_ptr<llvm::pdb::PDBSymbolExe> m_global_scope_up;
uint32_t m_cached_compile_unit_count;
- std::unique_ptr<lldb_private::CompilerDeclContext> m_tu_decl_ctx_up;
lldb_private::UniqueCStringMap<uint32_t> m_func_full_names;
lldb_private::UniqueCStringMap<uint32_t> m_func_base_names;
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index 08778bd1ba70..a1b21e51b0fe 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -1,13 +1,13 @@
//===-- SymbolFileSymtab.cpp ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "SymbolFileSymtab.h"
+
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -20,6 +20,8 @@
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Timer.h"
+#include <memory>
+
using namespace lldb;
using namespace lldb_private;
@@ -62,11 +64,9 @@ uint32_t SymbolFileSymtab::CalculateAbilities() {
if (m_obj_file) {
const Symtab *symtab = m_obj_file->GetSymtab();
if (symtab) {
- //----------------------------------------------------------------------
// The snippet of code below will get the indexes the module symbol table
// entries that are code, data, or function related (debug info), sort
// them by value (address) and dump the sorted symbols.
- //----------------------------------------------------------------------
if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile,
m_source_indexes)) {
abilities |= CompileUnits;
@@ -124,9 +124,9 @@ CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) {
const Symbol *cu_symbol =
m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
if (cu_symbol)
- cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL,
+ cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr,
cu_symbol->GetName().AsCString(), 0,
- eLanguageTypeUnknown, eLazyBoolNo));
+ eLanguageTypeUnknown, eLazyBoolNo);
}
return cu_sp;
}
@@ -139,8 +139,8 @@ size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) {
size_t num_added = 0;
// We must at least have a valid compile unit
const Symtab *symtab = m_obj_file->GetSymtab();
- const Symbol *curr_symbol = NULL;
- const Symbol *next_symbol = NULL;
+ const Symbol *curr_symbol = nullptr;
+ const Symbol *next_symbol = nullptr;
// const char *prefix = m_obj_file->SymbolPrefix();
// if (prefix == NULL)
// prefix == "";
@@ -188,10 +188,10 @@ size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) {
LLDB_INVALID_UID, // We don't have any type info
// for this function
curr_symbol->GetMangled(), // Linker/mangled name
- NULL, // no return type for a code symbol...
+ nullptr, // no return type for a code symbol...
func_range)); // first address range
- if (func_sp.get() != NULL) {
+ if (func_sp.get() != nullptr) {
comp_unit.AddFunction(func_sp);
++num_added;
}
@@ -219,7 +219,7 @@ bool SymbolFileSymtab::ParseSupportFiles(CompileUnit &comp_unit,
}
bool SymbolFileSymtab::ParseImportedModules(
- const SymbolContext &sc, std::vector<ConstString> &imported_modules) {
+ const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
return false;
}
@@ -230,7 +230,7 @@ size_t SymbolFileSymtab::ParseVariablesForContext(const SymbolContext &sc) {
}
Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) {
- return NULL;
+ return nullptr;
}
llvm::Optional<SymbolFile::ArrayInfo>
@@ -246,7 +246,7 @@ bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) {
uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
- if (m_obj_file->GetSymtab() == NULL)
+ if (m_obj_file->GetSymtab() == nullptr)
return 0;
uint32_t resolved_flags = 0;
@@ -259,9 +259,7 @@ uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr,
return resolved_flags;
}
-//------------------------------------------------------------------
// PluginInterface protocol
-//------------------------------------------------------------------
lldb_private::ConstString SymbolFileSymtab::GetPluginName() {
return GetPluginNameStatic();
}
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
index e4ec7a181333..bc9a531419ae 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
+++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -1,9 +1,8 @@
//===-- SymbolFileSymtab.h --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -18,16 +17,12 @@
class SymbolFileSymtab : public lldb_private::SymbolFile {
public:
- //------------------------------------------------------------------
// Constructors and Destructors
- //------------------------------------------------------------------
SymbolFileSymtab(lldb_private::ObjectFile *obj_file);
~SymbolFileSymtab() override;
- //------------------------------------------------------------------
// Static Functions
- //------------------------------------------------------------------
static void Initialize();
static void Terminate();
@@ -41,9 +36,7 @@ public:
uint32_t CalculateAbilities() override;
- //------------------------------------------------------------------
// Compile Unit function calls
- //------------------------------------------------------------------
uint32_t GetNumCompileUnits() override;
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
@@ -64,7 +57,7 @@ public:
bool ParseImportedModules(
const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) override;
+ std::vector<lldb_private::SourceModule> &imported_modules) override;
size_t ParseBlocksRecursive(lldb_private::Function &func) override;
@@ -86,9 +79,7 @@ public:
lldb::TypeClass type_mask,
lldb_private::TypeList &type_list) override;
- //------------------------------------------------------------------
// PluginInterface protocol
- //------------------------------------------------------------------
lldb_private::ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;