aboutsummaryrefslogtreecommitdiff
path: root/lib/DebugInfo/DWARF/DWARFFormValue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/DebugInfo/DWARF/DWARFFormValue.cpp')
-rw-r--r--lib/DebugInfo/DWARF/DWARFFormValue.cpp84
1 files changed, 62 insertions, 22 deletions
diff --git a/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index 7719fea63120..290d35511cdb 100644
--- a/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -1,9 +1,8 @@
//===- DWARFFormValue.cpp -------------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -78,6 +77,34 @@ static const DWARFFormValue::FormClass DWARF5FormClasses[] = {
};
+DWARFFormValue DWARFFormValue::createFromSValue(dwarf::Form F, int64_t V) {
+ return DWARFFormValue(F, ValueType(V));
+}
+
+DWARFFormValue DWARFFormValue::createFromUValue(dwarf::Form F, uint64_t V) {
+ return DWARFFormValue(F, ValueType(V));
+}
+
+DWARFFormValue DWARFFormValue::createFromPValue(dwarf::Form F, const char *V) {
+ return DWARFFormValue(F, ValueType(V));
+}
+
+DWARFFormValue DWARFFormValue::createFromBlockValue(dwarf::Form F,
+ ArrayRef<uint8_t> D) {
+ ValueType V;
+ V.uval = D.size();
+ V.data = D.data();
+ return DWARFFormValue(F, V);
+}
+
+DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U,
+ uint32_t *OffsetPtr) {
+ DWARFFormValue FormValue(F);
+ FormValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr,
+ U->getFormParams(), U);
+ return FormValue;
+}
+
bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
uint32_t *OffsetPtr,
const dwarf::FormParams Params) {
@@ -193,13 +220,17 @@ bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
default:
break;
}
- // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset.
- // Don't check for DWARF version here, as some producers may still do this
- // by mistake. Also accept DW_FORM_[line_]strp since these are
- // .debug_[line_]str section offsets.
- return (Form == DW_FORM_data4 || Form == DW_FORM_data8 ||
- Form == DW_FORM_strp || Form == DW_FORM_line_strp) &&
- FC == FC_SectionOffset;
+
+ if (FC == FC_SectionOffset) {
+ if (Form == DW_FORM_strp || Form == DW_FORM_line_strp)
+ return true;
+ // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section
+ // offset. If we don't have a DWARFUnit, default to the old behavior.
+ if (Form == DW_FORM_data4 || Form == DW_FORM_data8)
+ return !U || U->getVersion() <= 3;
+ }
+
+ return false;
}
bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
@@ -268,7 +299,7 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
case DW_FORM_data8:
case DW_FORM_ref8:
case DW_FORM_ref_sup8:
- Value.uval = Data.getU64(OffsetPtr);
+ Value.uval = Data.getRelocatedValue(8, OffsetPtr);
break;
case DW_FORM_data16:
// Treat this like a 16-byte block.
@@ -323,7 +354,7 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval);
Value.data = nullptr;
if (!Str.empty()) {
- Value.data = reinterpret_cast<const uint8_t *>(Str.data());
+ Value.data = Str.bytes_begin();
*OffsetPtr += Value.uval;
}
}
@@ -333,7 +364,7 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS,
DIDumpOptions DumpOpts,
- SectionedAddress SA) const {
+ object::SectionedAddress SA) const {
OS << format("0x%016" PRIx64, SA.Address);
dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts,
SA.SectionIndex);
@@ -370,12 +401,14 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
case DW_FORM_addrx3:
case DW_FORM_addrx4:
case DW_FORM_GNU_addr_index: {
- Optional<SectionedAddress> A = U->getAddrOffsetSectionItem(UValue);
+ if (U == nullptr) {
+ OS << "<invalid dwarf unit>";
+ break;
+ }
+ Optional<object::SectionedAddress> A = U->getAddrOffsetSectionItem(UValue);
if (!A || DumpOpts.Verbose)
AddrOS << format("indexed (%8.8x) address = ", (uint32_t)UValue);
- if (U == nullptr)
- OS << "<invalid dwarf unit>";
- else if (A)
+ if (A)
dumpSectionedAddress(AddrOS, DumpOpts, *A);
else
OS << "<no .debug_addr section>";
@@ -591,14 +624,15 @@ Optional<uint64_t> DWARFFormValue::getAsAddress() const {
return SA->Address;
return None;
}
-Optional<SectionedAddress> DWARFFormValue::getAsSectionedAddress() const {
+Optional<object::SectionedAddress>
+DWARFFormValue::getAsSectionedAddress() const {
if (!isFormClass(FC_Address))
return None;
if (Form == DW_FORM_GNU_addr_index || Form == DW_FORM_addrx) {
uint32_t Index = Value.uval;
if (!U)
return None;
- Optional<SectionedAddress> SA = U->getAddrOffsetSectionItem(Index);
+ Optional<object::SectionedAddress> SA = U->getAddrOffsetSectionItem(Index);
if (!SA)
return None;
return SA;
@@ -607,6 +641,12 @@ Optional<SectionedAddress> DWARFFormValue::getAsSectionedAddress() const {
}
Optional<uint64_t> DWARFFormValue::getAsReference() const {
+ if (auto R = getAsRelativeReference())
+ return R->Unit ? R->Unit->getOffset() + R->Offset : R->Offset;
+ return None;
+}
+
+Optional<DWARFFormValue::UnitOffset> DWARFFormValue::getAsRelativeReference() const {
if (!isFormClass(FC_Reference))
return None;
switch (Form) {
@@ -617,11 +657,11 @@ Optional<uint64_t> DWARFFormValue::getAsReference() const {
case DW_FORM_ref_udata:
if (!U)
return None;
- return Value.uval + U->getOffset();
+ return UnitOffset{const_cast<DWARFUnit*>(U), Value.uval};
case DW_FORM_ref_addr:
case DW_FORM_ref_sig8:
case DW_FORM_GNU_ref_alt:
- return Value.uval;
+ return UnitOffset{nullptr, Value.uval};
default:
return None;
}