aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/DebugInfo
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-08-02 17:42:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-08-02 17:42:12 +0000
commit1c4688a8498fea1db507842ff8dedaacad8ef77b (patch)
treee74f1bea0e682a4cd6d7edea69293ab7958eb9ae /contrib/llvm/lib/DebugInfo
parent68dc77c284115e8f103290474b3b9e35a3906c53 (diff)
parentb7eb8e35e481a74962664b63dfb09483b200209a (diff)
Merge llvm trunk r338150 (just before the 7.0.0 branch point), and
resolve conflicts.
Notes
Notes: svn path=/projects/clang700-import/; revision=337149
Diffstat (limited to 'contrib/llvm/lib/DebugInfo')
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/RecordName.cpp3
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp8
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp3
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp5
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp65
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp198
-rw-r--r--contrib/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp2
9 files changed, 277 insertions, 15 deletions
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/RecordName.cpp b/contrib/llvm/lib/DebugInfo/CodeView/RecordName.cpp
index e50c43a1d481..d868ae237a44 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/RecordName.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/RecordName.cpp
@@ -307,6 +307,9 @@ static int getSymbolNameOffset(CVSymbol Sym) {
// See BPRelativeSym
case SymbolKind::S_BPREL32:
return 8;
+ // See UsingNamespaceSym
+ case SymbolKind::S_UNAMESPACE:
+ return 0;
default:
return -1;
}
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp b/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
index af249adc9774..f8bf961f22a1 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
@@ -611,6 +611,12 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
return Error::success();
}
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ UsingNamespaceSym &UN) {
+ W.printString("Namespace", UN.Name);
+ return Error::success();
+}
+
Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) {
W.printNumber("Length", CVR.length());
return Error::success();
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp b/contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
index 923837a45d9f..e77c8e8f02f5 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
@@ -463,3 +463,11 @@ Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
return Error::success();
}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ UsingNamespaceSym &UN) {
+
+ error(IO.mapStringZ(UN.Name));
+
+ return Error::success();
+}
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp b/contrib/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
index 95082d4a8e03..839ab6f0a705 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
@@ -428,7 +428,7 @@ static bool discoverTypeIndices(ArrayRef<uint8_t> Content, SymbolKind Kind,
case SymbolKind::S_DEFRANGE_SUBFIELD:
break;
- // No type refernces.
+ // No type references.
case SymbolKind::S_LABEL32:
case SymbolKind::S_OBJNAME:
case SymbolKind::S_COMPILE:
@@ -439,6 +439,7 @@ static bool discoverTypeIndices(ArrayRef<uint8_t> Content, SymbolKind Kind,
case SymbolKind::S_FRAMEPROC:
case SymbolKind::S_THUNK32:
case SymbolKind::S_FRAMECOOKIE:
+ case SymbolKind::S_UNAMESPACE:
break;
// Scope ending symbols.
case SymbolKind::S_END:
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
index e4f39dd988e1..2e29c9d7dfa0 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
@@ -226,7 +226,10 @@ bool TypeStreamMerger::remapIndexFallback(TypeIndex &Idx,
if (IsSecondPass && MapPos >= Map.size()) {
// FIXME: Print a more useful error. We can give the current record and the
// index that we think its pointing to.
- LastError = joinErrors(std::move(*LastError), errorCorruptRecord());
+ if (LastError)
+ LastError = joinErrors(std::move(*LastError), errorCorruptRecord());
+ else
+ LastError = errorCorruptRecord();
}
++NumBadIndices;
diff --git a/contrib/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/contrib/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
index adada672af00..f49ab40fad9a 100644
--- a/contrib/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -38,7 +38,7 @@ DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
}
bool
-DWARFAbbreviationDeclaration::extract(DataExtractor Data,
+DWARFAbbreviationDeclaration::extract(DataExtractor Data,
uint32_t* OffsetPtr) {
clear();
const uint32_t Offset = *OffsetPtr;
diff --git a/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index da13c5047f77..9d2554ff9e2e 100644
--- a/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -17,6 +17,7 @@
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
@@ -249,6 +250,36 @@ static void dumpStringOffsetsSection(
}
}
+// Dump the .debug_addr section.
+static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
+ DIDumpOptions DumpOpts, uint16_t Version,
+ uint8_t AddrSize) {
+ // TODO: Make this more general: add callback types to Error.h, create
+ // implementation and make all DWARF classes use them.
+ static auto WarnCallback = [](Error Warn) {
+ handleAllErrors(std::move(Warn), [](ErrorInfoBase &Info) {
+ WithColor::warning() << Info.message() << '\n';
+ });
+ };
+ uint32_t Offset = 0;
+ while (AddrData.isValidOffset(Offset)) {
+ DWARFDebugAddrTable AddrTable;
+ uint32_t TableOffset = Offset;
+ if (Error Err = AddrTable.extract(AddrData, &Offset, Version,
+ AddrSize, WarnCallback)) {
+ WithColor::error() << toString(std::move(Err)) << '\n';
+ // Keep going after an error, if we can, assuming that the length field
+ // could be read. If it couldn't, stop reading the section.
+ if (!AddrTable.hasValidLength())
+ break;
+ uint64_t Length = AddrTable.getLength();
+ Offset = TableOffset + Length;
+ } else {
+ AddrTable.dump(OS, DumpOpts);
+ }
+ }
+}
+
// Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
static void dumpRnglistsSection(raw_ostream &OS,
DWARFDataExtractor &rnglistData,
@@ -455,18 +486,16 @@ void DWARFContext::dump(
}
}
+ if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
+ DObj->getAddrSection().Data)) {
+ DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(),
+ isLittleEndian(), 0);
+ dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());
+ }
+
if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
DObj->getRangeSection().Data)) {
- // In fact, different compile units may have different address byte
- // sizes, but for simplicity we just use the address byte size of the
- // last compile unit (there is no easy and fast way to associate address
- // range list and the compile unit it describes).
- // FIXME: savedAddressByteSize seems sketchy.
- uint8_t savedAddressByteSize = 0;
- for (const auto &CU : compile_units()) {
- savedAddressByteSize = CU->getAddressByteSize();
- break;
- }
+ uint8_t savedAddressByteSize = getCUAddrSize();
DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
isLittleEndian(), savedAddressByteSize);
uint32_t offset = 0;
@@ -474,7 +503,7 @@ void DWARFContext::dump(
while (rangesData.isValidOffset(offset)) {
if (Error E = rangeList.extract(rangesData, &offset)) {
WithColor::error() << toString(std::move(E)) << '\n';
- break;
+ break;
}
rangeList.dump(OS);
}
@@ -1584,3 +1613,17 @@ Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) {
RegInfo.reset(TheTarget->createMCRegInfo(TT.str()));
return Error::success();
}
+
+uint8_t DWARFContext::getCUAddrSize() {
+ // In theory, different compile units may have different address byte
+ // sizes, but for simplicity we just use the address byte size of the
+ // last compile unit. In practice the address size field is repeated across
+ // various DWARF headers (at least in version 5) to make it easier to dump
+ // them independently, not to enable varying the address size.
+ uint8_t Addr = 0;
+ for (const auto &CU : compile_units()) {
+ Addr = CU->getAddressByteSize();
+ break;
+ }
+ return Addr;
+}
diff --git a/contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp b/contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
new file mode 100644
index 000000000000..7085ca067ba6
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
@@ -0,0 +1,198 @@
+//===- DWARFDebugAddr.cpp -------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+
+using namespace llvm;
+
+void DWARFDebugAddrTable::clear() {
+ HeaderData = {};
+ Addrs.clear();
+ invalidateLength();
+}
+
+Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data,
+ uint32_t *OffsetPtr,
+ uint16_t Version,
+ uint8_t AddrSize,
+ std::function<void(Error)> WarnCallback) {
+ clear();
+ HeaderOffset = *OffsetPtr;
+ // Read and verify the length field.
+ if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t)))
+ return createStringError(errc::invalid_argument,
+ "section is not large enough to contain a "
+ ".debug_addr table length at offset 0x%"
+ PRIx32, *OffsetPtr);
+ uint16_t UnitVersion;
+ if (Version == 0) {
+ WarnCallback(createStringError(errc::invalid_argument,
+ "DWARF version is not defined in CU,"
+ " assuming version 5"));
+ UnitVersion = 5;
+ } else {
+ UnitVersion = Version;
+ }
+ // TODO: Add support for DWARF64.
+ Format = dwarf::DwarfFormat::DWARF32;
+ if (UnitVersion >= 5) {
+ HeaderData.Length = Data.getU32(OffsetPtr);
+ if (HeaderData.Length == 0xffffffffu) {
+ invalidateLength();
+ return createStringError(errc::not_supported,
+ "DWARF64 is not supported in .debug_addr at offset 0x%" PRIx32,
+ HeaderOffset);
+ }
+ if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header)) {
+ uint32_t TmpLength = getLength();
+ invalidateLength();
+ return createStringError(errc::invalid_argument,
+ ".debug_addr table at offset 0x%" PRIx32
+ " has too small length (0x%" PRIx32
+ ") to contain a complete header",
+ HeaderOffset, TmpLength);
+ }
+ uint32_t End = HeaderOffset + getLength();
+ if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset)) {
+ uint32_t TmpLength = getLength();
+ invalidateLength();
+ return createStringError(errc::invalid_argument,
+ "section is not large enough to contain a .debug_addr table "
+ "of length 0x%" PRIx32 " at offset 0x%" PRIx32,
+ TmpLength, HeaderOffset);
+ }
+
+ HeaderData.Version = Data.getU16(OffsetPtr);
+ HeaderData.AddrSize = Data.getU8(OffsetPtr);
+ HeaderData.SegSize = Data.getU8(OffsetPtr);
+ DataSize = getDataSize();
+ } else {
+ HeaderData.Version = UnitVersion;
+ HeaderData.AddrSize = AddrSize;
+ // TODO: Support for non-zero SegSize.
+ HeaderData.SegSize = 0;
+ DataSize = Data.size();
+ }
+
+ // Perform basic validation of the remaining header fields.
+
+ // We support DWARF version 5 for now as well as pre-DWARF5
+ // implementations of .debug_addr table, which doesn't contain a header
+ // and consists only of a series of addresses.
+ if (HeaderData.Version > 5) {
+ return createStringError(errc::not_supported, "version %" PRIu16
+ " of .debug_addr section at offset 0x%" PRIx32 " is not supported",
+ HeaderData.Version, HeaderOffset);
+ }
+ // FIXME: For now we just treat version mismatch as an error,
+ // however the correct way to associate a .debug_addr table
+ // with a .debug_info table is to look at the DW_AT_addr_base
+ // attribute in the info table.
+ if (HeaderData.Version != UnitVersion)
+ return createStringError(errc::invalid_argument,
+ ".debug_addr table at offset 0x%" PRIx32
+ " has version %" PRIu16
+ " which is different from the version suggested"
+ " by the DWARF unit header: %" PRIu16,
+ HeaderOffset, HeaderData.Version, UnitVersion);
+ if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
+ return createStringError(errc::not_supported,
+ ".debug_addr table at offset 0x%" PRIx32
+ " has unsupported address size %" PRIu8,
+ HeaderOffset, HeaderData.AddrSize);
+ if (HeaderData.AddrSize != AddrSize && AddrSize != 0)
+ return createStringError(errc::invalid_argument,
+ ".debug_addr table at offset 0x%" PRIx32
+ " has address size %" PRIu8
+ " which is different from CU address size %" PRIu8,
+ HeaderOffset, HeaderData.AddrSize, AddrSize);
+
+ // TODO: add support for non-zero segment selector size.
+ if (HeaderData.SegSize != 0)
+ return createStringError(errc::not_supported,
+ ".debug_addr table at offset 0x%" PRIx32
+ " has unsupported segment selector size %" PRIu8,
+ HeaderOffset, HeaderData.SegSize);
+ if (DataSize % HeaderData.AddrSize != 0) {
+ invalidateLength();
+ return createStringError(errc::invalid_argument,
+ ".debug_addr table at offset 0x%" PRIx32
+ " contains data of size %" PRIu32
+ " which is not a multiple of addr size %" PRIu8,
+ HeaderOffset, DataSize, HeaderData.AddrSize);
+ }
+ Data.setAddressSize(HeaderData.AddrSize);
+ uint32_t AddrCount = DataSize / HeaderData.AddrSize;
+ for (uint32_t I = 0; I < AddrCount; ++I)
+ if (HeaderData.AddrSize == 4)
+ Addrs.push_back(Data.getU32(OffsetPtr));
+ else
+ Addrs.push_back(Data.getU64(OffsetPtr));
+ return Error::success();
+}
+
+void DWARFDebugAddrTable::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
+ if (DumpOpts.Verbose)
+ OS << format("0x%8.8" PRIx32 ": ", HeaderOffset);
+ OS << format("Addr Section: length = 0x%8.8" PRIx32
+ ", version = 0x%4.4" PRIx16 ", "
+ "addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8 "\n",
+ HeaderData.Length, HeaderData.Version, HeaderData.AddrSize,
+ HeaderData.SegSize);
+
+ static const char *Fmt32 = "0x%8.8" PRIx32;
+ static const char *Fmt64 = "0x%16.16" PRIx64;
+ std::string AddrFmt = "\n";
+ std::string AddrFmtVerbose = " => ";
+ if (HeaderData.AddrSize == 4) {
+ AddrFmt.append(Fmt32);
+ AddrFmtVerbose.append(Fmt32);
+ }
+ else {
+ AddrFmt.append(Fmt64);
+ AddrFmtVerbose.append(Fmt64);
+ }
+
+ if (Addrs.size() > 0) {
+ OS << "Addrs: [";
+ for (uint64_t Addr : Addrs) {
+ OS << format(AddrFmt.c_str(), Addr);
+ if (DumpOpts.Verbose)
+ OS << format(AddrFmtVerbose.c_str(),
+ Addr + HeaderOffset + sizeof(HeaderData));
+ }
+ OS << "\n]\n";
+ }
+}
+
+Expected<uint64_t> DWARFDebugAddrTable::getAddrEntry(uint32_t Index) const {
+ if (Index < Addrs.size())
+ return Addrs[Index];
+ return createStringError(errc::invalid_argument,
+ "Index %" PRIu32 " is out of range of the "
+ ".debug_addr table at offset 0x%" PRIx32,
+ Index, HeaderOffset);
+}
+
+uint32_t DWARFDebugAddrTable::getLength() const {
+ if (HeaderData.Length == 0)
+ return 0;
+ // TODO: DWARF64 support.
+ return HeaderData.Length + sizeof(uint32_t);
+}
+
+uint32_t DWARFDebugAddrTable::getDataSize() const {
+ if (DataSize != 0)
+ return DataSize;
+ if (getLength() == 0)
+ return 0;
+ return getLength() - getHeaderSize();
+}
diff --git a/contrib/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/contrib/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
index 2a89faff9647..08be524ab464 100644
--- a/contrib/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+++ b/contrib/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
@@ -155,7 +155,7 @@ std::error_code SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol,
// of the function's code, not the descriptor.
uint64_t OpdOffset = SymbolAddress - OpdAddress;
uint32_t OpdOffset32 = OpdOffset;
- if (OpdOffset == OpdOffset32 &&
+ if (OpdOffset == OpdOffset32 &&
OpdExtractor->isValidOffsetForAddress(OpdOffset32))
SymbolAddress = OpdExtractor->getAddress(&OpdOffset32);
}