You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.167
Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
parent
e19d552987
commit
b084638f15
30
external/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
vendored
30
external/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
vendored
@ -1,30 +0,0 @@
|
||||
add_llvm_library(LLVMDebugInfoDWARF
|
||||
DWARFAbbreviationDeclaration.cpp
|
||||
DWARFAcceleratorTable.cpp
|
||||
DWARFCompileUnit.cpp
|
||||
DWARFContext.cpp
|
||||
DWARFDataExtractor.cpp
|
||||
DWARFDebugAbbrev.cpp
|
||||
DWARFDebugArangeSet.cpp
|
||||
DWARFDebugAranges.cpp
|
||||
DWARFDebugFrame.cpp
|
||||
DWARFDebugInfoEntry.cpp
|
||||
DWARFDebugLine.cpp
|
||||
DWARFDebugLoc.cpp
|
||||
DWARFDebugMacro.cpp
|
||||
DWARFDebugPubTable.cpp
|
||||
DWARFDebugRangeList.cpp
|
||||
DWARFDie.cpp
|
||||
DWARFExpression.cpp
|
||||
DWARFFormValue.cpp
|
||||
DWARFGdbIndex.cpp
|
||||
DWARFTypeUnit.cpp
|
||||
DWARFUnitIndex.cpp
|
||||
DWARFUnit.cpp
|
||||
DWARFVerifier.cpp
|
||||
SyntaxHighlighting.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/DWARF
|
||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo
|
||||
)
|
@ -1,232 +0,0 @@
|
||||
//===- DWARFAbbreviationDeclaration.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/DWARFAbbreviationDeclaration.h"
|
||||
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||
#include "llvm/Support/DataExtractor.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace dwarf;
|
||||
|
||||
void DWARFAbbreviationDeclaration::clear() {
|
||||
Code = 0;
|
||||
Tag = DW_TAG_null;
|
||||
CodeByteSize = 0;
|
||||
HasChildren = false;
|
||||
AttributeSpecs.clear();
|
||||
FixedAttributeSize.reset();
|
||||
}
|
||||
|
||||
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
|
||||
clear();
|
||||
}
|
||||
|
||||
bool
|
||||
DWARFAbbreviationDeclaration::extract(DataExtractor Data,
|
||||
uint32_t* OffsetPtr) {
|
||||
clear();
|
||||
const uint32_t Offset = *OffsetPtr;
|
||||
Code = Data.getULEB128(OffsetPtr);
|
||||
if (Code == 0) {
|
||||
return false;
|
||||
}
|
||||
CodeByteSize = *OffsetPtr - Offset;
|
||||
Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
|
||||
if (Tag == DW_TAG_null) {
|
||||
clear();
|
||||
return false;
|
||||
}
|
||||
uint8_t ChildrenByte = Data.getU8(OffsetPtr);
|
||||
HasChildren = (ChildrenByte == DW_CHILDREN_yes);
|
||||
// Assign a value to our optional FixedAttributeSize member variable. If
|
||||
// this member variable still has a value after the while loop below, then
|
||||
// all attribute data in this abbreviation declaration has a fixed byte size.
|
||||
FixedAttributeSize = FixedSizeInfo();
|
||||
|
||||
// Read all of the abbreviation attributes and forms.
|
||||
while (true) {
|
||||
auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
|
||||
auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
|
||||
if (A && F) {
|
||||
bool IsImplicitConst = (F == DW_FORM_implicit_const);
|
||||
if (IsImplicitConst) {
|
||||
int64_t V = Data.getSLEB128(OffsetPtr);
|
||||
AttributeSpecs.push_back(AttributeSpec(A, F, V));
|
||||
continue;
|
||||
}
|
||||
Optional<uint8_t> ByteSize;
|
||||
// If this abbrevation still has a fixed byte size, then update the
|
||||
// FixedAttributeSize as needed.
|
||||
switch (F) {
|
||||
case DW_FORM_addr:
|
||||
if (FixedAttributeSize)
|
||||
++FixedAttributeSize->NumAddrs;
|
||||
break;
|
||||
|
||||
case DW_FORM_ref_addr:
|
||||
if (FixedAttributeSize)
|
||||
++FixedAttributeSize->NumRefAddrs;
|
||||
break;
|
||||
|
||||
case DW_FORM_strp:
|
||||
case DW_FORM_GNU_ref_alt:
|
||||
case DW_FORM_GNU_strp_alt:
|
||||
case DW_FORM_line_strp:
|
||||
case DW_FORM_sec_offset:
|
||||
case DW_FORM_strp_sup:
|
||||
if (FixedAttributeSize)
|
||||
++FixedAttributeSize->NumDwarfOffsets;
|
||||
break;
|
||||
|
||||
default:
|
||||
// The form has a byte size that doesn't depend on Params.
|
||||
// If it's a fixed size, keep track of it.
|
||||
if ((ByteSize =
|
||||
DWARFFormValue::getFixedByteSize(F, DWARFFormParams()))) {
|
||||
if (FixedAttributeSize)
|
||||
FixedAttributeSize->NumBytes += *ByteSize;
|
||||
break;
|
||||
}
|
||||
// Indicate we no longer have a fixed byte size for this
|
||||
// abbreviation by clearing the FixedAttributeSize optional value
|
||||
// so it doesn't have a value.
|
||||
FixedAttributeSize.reset();
|
||||
break;
|
||||
}
|
||||
// Record this attribute and its fixed size if it has one.
|
||||
AttributeSpecs.push_back(AttributeSpec(A, F, ByteSize));
|
||||
} else if (A == 0 && F == 0) {
|
||||
// We successfully reached the end of this abbreviation declaration
|
||||
// since both attribute and form are zero.
|
||||
break;
|
||||
} else {
|
||||
// Attribute and form pairs must either both be non-zero, in which case
|
||||
// they are added to the abbreviation declaration, or both be zero to
|
||||
// terminate the abbrevation declaration. In this case only one was
|
||||
// zero which is an error.
|
||||
clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
|
||||
auto tagString = TagString(getTag());
|
||||
OS << '[' << getCode() << "] ";
|
||||
if (!tagString.empty())
|
||||
OS << tagString;
|
||||
else
|
||||
OS << format("DW_TAG_Unknown_%x", getTag());
|
||||
OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
|
||||
for (const AttributeSpec &Spec : AttributeSpecs) {
|
||||
OS << '\t';
|
||||
auto attrString = AttributeString(Spec.Attr);
|
||||
if (!attrString.empty())
|
||||
OS << attrString;
|
||||
else
|
||||
OS << format("DW_AT_Unknown_%x", Spec.Attr);
|
||||
OS << '\t';
|
||||
auto formString = FormEncodingString(Spec.Form);
|
||||
if (!formString.empty())
|
||||
OS << formString;
|
||||
else
|
||||
OS << format("DW_FORM_Unknown_%x", Spec.Form);
|
||||
if (Spec.isImplicitConst())
|
||||
OS << '\t' << Spec.getImplicitConstValue();
|
||||
OS << '\n';
|
||||
}
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
Optional<uint32_t>
|
||||
DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
|
||||
for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
|
||||
if (AttributeSpecs[i].Attr == Attr)
|
||||
return i;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
|
||||
const uint32_t DIEOffset, const dwarf::Attribute Attr,
|
||||
const DWARFUnit &U) const {
|
||||
Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
|
||||
if (!MatchAttrIndex)
|
||||
return None;
|
||||
|
||||
auto DebugInfoData = U.getDebugInfoExtractor();
|
||||
|
||||
// Add the byte size of ULEB that for the abbrev Code so we can start
|
||||
// skipping the attribute data.
|
||||
uint32_t Offset = DIEOffset + CodeByteSize;
|
||||
uint32_t AttrIndex = 0;
|
||||
for (const auto &Spec : AttributeSpecs) {
|
||||
if (*MatchAttrIndex == AttrIndex) {
|
||||
// We have arrived at the attribute to extract, extract if from Offset.
|
||||
DWARFFormValue FormValue(Spec.Form);
|
||||
if (Spec.isImplicitConst()) {
|
||||
FormValue.setSValue(Spec.getImplicitConstValue());
|
||||
return FormValue;
|
||||
}
|
||||
if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
|
||||
return FormValue;
|
||||
}
|
||||
// March Offset along until we get to the attribute we want.
|
||||
if (auto FixedSize = Spec.getByteSize(U))
|
||||
Offset += *FixedSize;
|
||||
else
|
||||
DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset,
|
||||
U.getFormParams());
|
||||
++AttrIndex;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
|
||||
const DWARFUnit &U) const {
|
||||
size_t ByteSize = NumBytes;
|
||||
if (NumAddrs)
|
||||
ByteSize += NumAddrs * U.getAddressByteSize();
|
||||
if (NumRefAddrs)
|
||||
ByteSize += NumRefAddrs * U.getRefAddrByteSize();
|
||||
if (NumDwarfOffsets)
|
||||
ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
|
||||
return ByteSize;
|
||||
}
|
||||
|
||||
Optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize(
|
||||
const DWARFUnit &U) const {
|
||||
if (isImplicitConst())
|
||||
return 0;
|
||||
if (ByteSize.HasByteSize)
|
||||
return ByteSize.ByteSize;
|
||||
Optional<int64_t> S;
|
||||
auto FixedByteSize =
|
||||
DWARFFormValue::getFixedByteSize(Form, U.getFormParams());
|
||||
if (FixedByteSize)
|
||||
S = *FixedByteSize;
|
||||
return S;
|
||||
}
|
||||
|
||||
Optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize(
|
||||
const DWARFUnit &U) const {
|
||||
if (FixedAttributeSize)
|
||||
return FixedAttributeSize->getByteSize(U);
|
||||
return None;
|
||||
}
|
@ -1,268 +0,0 @@
|
||||
//===- DWARFAcceleratorTable.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/DWARFAcceleratorTable.h"
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
llvm::Error DWARFAcceleratorTable::extract() {
|
||||
uint32_t Offset = 0;
|
||||
|
||||
// Check that we can at least read the header.
|
||||
if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength)+4))
|
||||
return make_error<StringError>("Section too small: cannot read header.",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
Hdr.Magic = AccelSection.getU32(&Offset);
|
||||
Hdr.Version = AccelSection.getU16(&Offset);
|
||||
Hdr.HashFunction = AccelSection.getU16(&Offset);
|
||||
Hdr.NumBuckets = AccelSection.getU32(&Offset);
|
||||
Hdr.NumHashes = AccelSection.getU32(&Offset);
|
||||
Hdr.HeaderDataLength = AccelSection.getU32(&Offset);
|
||||
|
||||
// Check that we can read all the hashes and offsets from the
|
||||
// section (see SourceLevelDebugging.rst for the structure of the index).
|
||||
// We need to substract one because we're checking for an *offset* which is
|
||||
// equal to the size for an empty table and hence pointer after the section.
|
||||
if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength +
|
||||
Hdr.NumBuckets * 4 + Hdr.NumHashes * 8 - 1))
|
||||
return make_error<StringError>(
|
||||
"Section too small: cannot read buckets and hashes.",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
HdrData.DIEOffsetBase = AccelSection.getU32(&Offset);
|
||||
uint32_t NumAtoms = AccelSection.getU32(&Offset);
|
||||
|
||||
for (unsigned i = 0; i < NumAtoms; ++i) {
|
||||
uint16_t AtomType = AccelSection.getU16(&Offset);
|
||||
auto AtomForm = static_cast<dwarf::Form>(AccelSection.getU16(&Offset));
|
||||
HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
|
||||
}
|
||||
|
||||
IsValid = true;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
uint32_t DWARFAcceleratorTable::getNumBuckets() { return Hdr.NumBuckets; }
|
||||
uint32_t DWARFAcceleratorTable::getNumHashes() { return Hdr.NumHashes; }
|
||||
uint32_t DWARFAcceleratorTable::getSizeHdr() { return sizeof(Hdr); }
|
||||
uint32_t DWARFAcceleratorTable::getHeaderDataLength() {
|
||||
return Hdr.HeaderDataLength;
|
||||
}
|
||||
|
||||
ArrayRef<std::pair<DWARFAcceleratorTable::HeaderData::AtomType,
|
||||
DWARFAcceleratorTable::HeaderData::Form>>
|
||||
DWARFAcceleratorTable::getAtomsDesc() {
|
||||
return HdrData.Atoms;
|
||||
}
|
||||
|
||||
bool DWARFAcceleratorTable::validateForms() {
|
||||
for (auto Atom : getAtomsDesc()) {
|
||||
DWARFFormValue FormValue(Atom.second);
|
||||
switch (Atom.first) {
|
||||
case dwarf::DW_ATOM_die_offset:
|
||||
case dwarf::DW_ATOM_die_tag:
|
||||
case dwarf::DW_ATOM_type_flags:
|
||||
if ((!FormValue.isFormClass(DWARFFormValue::FC_Constant) &&
|
||||
!FormValue.isFormClass(DWARFFormValue::FC_Flag)) ||
|
||||
FormValue.getForm() == dwarf::DW_FORM_sdata)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::pair<uint32_t, dwarf::Tag>
|
||||
DWARFAcceleratorTable::readAtoms(uint32_t &HashDataOffset) {
|
||||
uint32_t DieOffset = dwarf::DW_INVALID_OFFSET;
|
||||
dwarf::Tag DieTag = dwarf::DW_TAG_null;
|
||||
DWARFFormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
|
||||
|
||||
for (auto Atom : getAtomsDesc()) {
|
||||
DWARFFormValue FormValue(Atom.second);
|
||||
FormValue.extractValue(AccelSection, &HashDataOffset, FormParams);
|
||||
switch (Atom.first) {
|
||||
case dwarf::DW_ATOM_die_offset:
|
||||
DieOffset = *FormValue.getAsUnsignedConstant();
|
||||
break;
|
||||
case dwarf::DW_ATOM_die_tag:
|
||||
DieTag = (dwarf::Tag)*FormValue.getAsUnsignedConstant();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {DieOffset, DieTag};
|
||||
}
|
||||
|
||||
LLVM_DUMP_METHOD void DWARFAcceleratorTable::dump(raw_ostream &OS) const {
|
||||
if (!IsValid)
|
||||
return;
|
||||
|
||||
// Dump the header.
|
||||
OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n'
|
||||
<< "Version = " << format("0x%04x", Hdr.Version) << '\n'
|
||||
<< "Hash function = " << format("0x%08x", Hdr.HashFunction) << '\n'
|
||||
<< "Bucket count = " << Hdr.NumBuckets << '\n'
|
||||
<< "Hashes count = " << Hdr.NumHashes << '\n'
|
||||
<< "HeaderData length = " << Hdr.HeaderDataLength << '\n'
|
||||
<< "DIE offset base = " << HdrData.DIEOffsetBase << '\n'
|
||||
<< "Number of atoms = " << HdrData.Atoms.size() << '\n';
|
||||
|
||||
unsigned i = 0;
|
||||
SmallVector<DWARFFormValue, 3> AtomForms;
|
||||
for (const auto &Atom: HdrData.Atoms) {
|
||||
OS << format("Atom[%d] Type: ", i++);
|
||||
auto TypeString = dwarf::AtomTypeString(Atom.first);
|
||||
if (!TypeString.empty())
|
||||
OS << TypeString;
|
||||
else
|
||||
OS << format("DW_ATOM_Unknown_0x%x", Atom.first);
|
||||
OS << " Form: ";
|
||||
auto FormString = dwarf::FormEncodingString(Atom.second);
|
||||
if (!FormString.empty())
|
||||
OS << FormString;
|
||||
else
|
||||
OS << format("DW_FORM_Unknown_0x%x", Atom.second);
|
||||
OS << '\n';
|
||||
AtomForms.push_back(DWARFFormValue(Atom.second));
|
||||
}
|
||||
|
||||
// Now go through the actual tables and dump them.
|
||||
uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
|
||||
unsigned HashesBase = Offset + Hdr.NumBuckets * 4;
|
||||
unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4;
|
||||
DWARFFormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
|
||||
|
||||
for (unsigned Bucket = 0; Bucket < Hdr.NumBuckets; ++Bucket) {
|
||||
unsigned Index = AccelSection.getU32(&Offset);
|
||||
|
||||
OS << format("Bucket[%d]\n", Bucket);
|
||||
if (Index == UINT32_MAX) {
|
||||
OS << " EMPTY\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
for (unsigned HashIdx = Index; HashIdx < Hdr.NumHashes; ++HashIdx) {
|
||||
unsigned HashOffset = HashesBase + HashIdx*4;
|
||||
unsigned OffsetsOffset = OffsetsBase + HashIdx*4;
|
||||
uint32_t Hash = AccelSection.getU32(&HashOffset);
|
||||
|
||||
if (Hash % Hdr.NumBuckets != Bucket)
|
||||
break;
|
||||
|
||||
unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
|
||||
OS << format(" Hash = 0x%08x Offset = 0x%08x\n", Hash, DataOffset);
|
||||
if (!AccelSection.isValidOffset(DataOffset)) {
|
||||
OS << " Invalid section offset\n";
|
||||
continue;
|
||||
}
|
||||
while (AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) {
|
||||
unsigned StringOffset = AccelSection.getRelocatedValue(4, &DataOffset);
|
||||
if (!StringOffset)
|
||||
break;
|
||||
OS << format(" Name: %08x \"%s\"\n", StringOffset,
|
||||
StringSection.getCStr(&StringOffset));
|
||||
unsigned NumData = AccelSection.getU32(&DataOffset);
|
||||
for (unsigned Data = 0; Data < NumData; ++Data) {
|
||||
OS << format(" Data[%d] => ", Data);
|
||||
unsigned i = 0;
|
||||
for (auto &Atom : AtomForms) {
|
||||
OS << format("{Atom[%d]: ", i++);
|
||||
if (Atom.extractValue(AccelSection, &DataOffset, FormParams))
|
||||
Atom.dump(OS);
|
||||
else
|
||||
OS << "Error extracting the value";
|
||||
OS << "} ";
|
||||
}
|
||||
OS << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWARFAcceleratorTable::ValueIterator::ValueIterator(
|
||||
const DWARFAcceleratorTable &AccelTable, unsigned Offset)
|
||||
: AccelTable(&AccelTable), DataOffset(Offset) {
|
||||
if (!AccelTable.AccelSection.isValidOffsetForDataOfSize(DataOffset, 4))
|
||||
return;
|
||||
|
||||
for (const auto &Atom : AccelTable.HdrData.Atoms)
|
||||
AtomForms.push_back(DWARFFormValue(Atom.second));
|
||||
|
||||
// Read the first entry.
|
||||
NumData = AccelTable.AccelSection.getU32(&DataOffset);
|
||||
Next();
|
||||
}
|
||||
|
||||
void DWARFAcceleratorTable::ValueIterator::Next() {
|
||||
assert(NumData > 0 && "attempted to increment iterator past the end");
|
||||
auto &AccelSection = AccelTable->AccelSection;
|
||||
if (Data >= NumData ||
|
||||
!AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) {
|
||||
NumData = 0;
|
||||
return;
|
||||
}
|
||||
DWARFFormParams FormParams = {AccelTable->Hdr.Version, 0,
|
||||
dwarf::DwarfFormat::DWARF32};
|
||||
for (auto &Atom : AtomForms)
|
||||
Atom.extractValue(AccelSection, &DataOffset, FormParams);
|
||||
++Data;
|
||||
}
|
||||
|
||||
iterator_range<DWARFAcceleratorTable::ValueIterator>
|
||||
DWARFAcceleratorTable::equal_range(StringRef Key) const {
|
||||
if (!IsValid)
|
||||
return make_range(ValueIterator(), ValueIterator());
|
||||
|
||||
// Find the bucket.
|
||||
unsigned HashValue = dwarf::djbHash(Key);
|
||||
unsigned Bucket = HashValue % Hdr.NumBuckets;
|
||||
unsigned BucketBase = sizeof(Hdr) + Hdr.HeaderDataLength;
|
||||
unsigned HashesBase = BucketBase + Hdr.NumBuckets * 4;
|
||||
unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4;
|
||||
|
||||
unsigned BucketOffset = BucketBase + Bucket * 4;
|
||||
unsigned Index = AccelSection.getU32(&BucketOffset);
|
||||
|
||||
// Search through all hashes in the bucket.
|
||||
for (unsigned HashIdx = Index; HashIdx < Hdr.NumHashes; ++HashIdx) {
|
||||
unsigned HashOffset = HashesBase + HashIdx * 4;
|
||||
unsigned OffsetsOffset = OffsetsBase + HashIdx * 4;
|
||||
uint32_t Hash = AccelSection.getU32(&HashOffset);
|
||||
|
||||
if (Hash % Hdr.NumBuckets != Bucket)
|
||||
// We are already in the next bucket.
|
||||
break;
|
||||
|
||||
unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
|
||||
unsigned StringOffset = AccelSection.getRelocatedValue(4, &DataOffset);
|
||||
if (!StringOffset)
|
||||
break;
|
||||
|
||||
// Finally, compare the key.
|
||||
if (Key == StringSection.getCStr(&StringOffset))
|
||||
return make_range({*this, DataOffset}, ValueIterator());
|
||||
}
|
||||
return make_range(ValueIterator(), ValueIterator());
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
//===-- DWARFCompileUnit.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/DWARFCompileUnit.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
|
||||
OS << format("0x%08x", getOffset()) << ": Compile Unit:"
|
||||
<< " length = " << format("0x%08x", getLength())
|
||||
<< " version = " << format("0x%04x", getVersion());
|
||||
if (getVersion() >= 5)
|
||||
OS << " unit_type = " << dwarf::UnitTypeString(getUnitType());
|
||||
OS << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset())
|
||||
<< " addr_size = " << format("0x%02x", getAddressByteSize())
|
||||
<< " (next unit at " << format("0x%08x", getNextUnitOffset())
|
||||
<< ")\n";
|
||||
|
||||
if (DWARFDie CUDie = getUnitDIE(false))
|
||||
CUDie.dump(OS, 0, DumpOpts);
|
||||
else
|
||||
OS << "<compile unit can't be parsed!>\n\n";
|
||||
}
|
||||
|
||||
// VTable anchor.
|
||||
DWARFCompileUnit::~DWARFCompileUnit() = default;
|
1517
external/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
vendored
1517
external/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
vendored
File diff suppressed because it is too large
Load Diff
@ -1,27 +0,0 @@
|
||||
//===- DWARFDataExtractor.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/DWARFDataExtractor.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
|
||||
uint64_t *SecNdx) const {
|
||||
if (SecNdx)
|
||||
*SecNdx = -1ULL;
|
||||
if (!Section)
|
||||
return getUnsigned(Off, Size);
|
||||
Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off);
|
||||
if (!Rel)
|
||||
return getUnsigned(Off, Size);
|
||||
if (SecNdx)
|
||||
*SecNdx = Rel->SectionIndex;
|
||||
return getUnsigned(Off, Size) + Rel->Value;
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
//===- DWARFDebugAbbrev.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/DWARFDebugAbbrev.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void DWARFAbbreviationDeclarationSet::clear() {
|
||||
Offset = 0;
|
||||
FirstAbbrCode = 0;
|
||||
Decls.clear();
|
||||
}
|
||||
|
||||
bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
|
||||
uint32_t *OffsetPtr) {
|
||||
clear();
|
||||
const uint32_t BeginOffset = *OffsetPtr;
|
||||
Offset = BeginOffset;
|
||||
DWARFAbbreviationDeclaration AbbrDecl;
|
||||
uint32_t PrevAbbrCode = 0;
|
||||
while (AbbrDecl.extract(Data, OffsetPtr)) {
|
||||
if (FirstAbbrCode == 0) {
|
||||
FirstAbbrCode = AbbrDecl.getCode();
|
||||
} else {
|
||||
if (PrevAbbrCode + 1 != AbbrDecl.getCode()) {
|
||||
// Codes are not consecutive, can't do O(1) lookups.
|
||||
FirstAbbrCode = UINT32_MAX;
|
||||
}
|
||||
}
|
||||
PrevAbbrCode = AbbrDecl.getCode();
|
||||
Decls.push_back(std::move(AbbrDecl));
|
||||
}
|
||||
return BeginOffset != *OffsetPtr;
|
||||
}
|
||||
|
||||
void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
|
||||
for (const auto &Decl : Decls)
|
||||
Decl.dump(OS);
|
||||
}
|
||||
|
||||
const DWARFAbbreviationDeclaration *
|
||||
DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
|
||||
uint32_t AbbrCode) const {
|
||||
if (FirstAbbrCode == UINT32_MAX) {
|
||||
for (const auto &Decl : Decls) {
|
||||
if (Decl.getCode() == AbbrCode)
|
||||
return &Decl;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size())
|
||||
return nullptr;
|
||||
return &Decls[AbbrCode - FirstAbbrCode];
|
||||
}
|
||||
|
||||
DWARFDebugAbbrev::DWARFDebugAbbrev() { clear(); }
|
||||
|
||||
void DWARFDebugAbbrev::clear() {
|
||||
AbbrDeclSets.clear();
|
||||
PrevAbbrOffsetPos = AbbrDeclSets.end();
|
||||
}
|
||||
|
||||
void DWARFDebugAbbrev::extract(DataExtractor Data) {
|
||||
clear();
|
||||
this->Data = Data;
|
||||
}
|
||||
|
||||
void DWARFDebugAbbrev::parse() const {
|
||||
if (!Data)
|
||||
return;
|
||||
uint32_t Offset = 0;
|
||||
DWARFAbbreviationDeclarationSet AbbrDecls;
|
||||
auto I = AbbrDeclSets.begin();
|
||||
while (Data->isValidOffset(Offset)) {
|
||||
while (I != AbbrDeclSets.end() && I->first < Offset)
|
||||
++I;
|
||||
uint32_t CUAbbrOffset = Offset;
|
||||
if (!AbbrDecls.extract(*Data, &Offset))
|
||||
break;
|
||||
AbbrDeclSets.insert(I, std::make_pair(CUAbbrOffset, std::move(AbbrDecls)));
|
||||
}
|
||||
Data = None;
|
||||
}
|
||||
|
||||
void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
|
||||
parse();
|
||||
|
||||
if (AbbrDeclSets.empty()) {
|
||||
OS << "< EMPTY >\n";
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto &I : AbbrDeclSets) {
|
||||
OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first);
|
||||
I.second.dump(OS);
|
||||
}
|
||||
}
|
||||
|
||||
const DWARFAbbreviationDeclarationSet*
|
||||
DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
|
||||
const auto End = AbbrDeclSets.end();
|
||||
if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) {
|
||||
return &(PrevAbbrOffsetPos->second);
|
||||
}
|
||||
|
||||
const auto Pos = AbbrDeclSets.find(CUAbbrOffset);
|
||||
if (Pos != End) {
|
||||
PrevAbbrOffsetPos = Pos;
|
||||
return &(Pos->second);
|
||||
}
|
||||
|
||||
if (Data && CUAbbrOffset < Data->getData().size()) {
|
||||
uint32_t Offset = CUAbbrOffset;
|
||||
DWARFAbbreviationDeclarationSet AbbrDecls;
|
||||
if (!AbbrDecls.extract(*Data, &Offset))
|
||||
return nullptr;
|
||||
PrevAbbrOffsetPos =
|
||||
AbbrDeclSets.insert(std::make_pair(CUAbbrOffset, std::move(AbbrDecls)))
|
||||
.first;
|
||||
return &PrevAbbrOffsetPos->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
//===- DWARFDebugArangeSet.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/DWARFDebugArangeSet.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
#include <cinttypes>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
void DWARFDebugArangeSet::clear() {
|
||||
Offset = -1U;
|
||||
std::memset(&HeaderData, 0, sizeof(Header));
|
||||
ArangeDescriptors.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
DWARFDebugArangeSet::extract(DataExtractor data, uint32_t *offset_ptr) {
|
||||
if (data.isValidOffset(*offset_ptr)) {
|
||||
ArangeDescriptors.clear();
|
||||
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.
|
||||
HeaderData.Length = data.getU32(offset_ptr);
|
||||
HeaderData.Version = data.getU16(offset_ptr);
|
||||
HeaderData.CuOffset = data.getU32(offset_ptr);
|
||||
HeaderData.AddrSize = data.getU8(offset_ptr);
|
||||
HeaderData.SegSize = data.getU8(offset_ptr);
|
||||
|
||||
// Perform basic validation of the header fields.
|
||||
if (!data.isValidOffsetForDataOfSize(Offset, HeaderData.Length) ||
|
||||
(HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)) {
|
||||
clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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 - Offset;
|
||||
const uint32_t tuple_size = HeaderData.AddrSize * 2;
|
||||
uint32_t first_tuple_offset = 0;
|
||||
while (first_tuple_offset < header_size)
|
||||
first_tuple_offset += tuple_size;
|
||||
|
||||
*offset_ptr = Offset + first_tuple_offset;
|
||||
|
||||
Descriptor arangeDescriptor;
|
||||
|
||||
static_assert(sizeof(arangeDescriptor.Address) ==
|
||||
sizeof(arangeDescriptor.Length),
|
||||
"Different datatypes for addresses and sizes!");
|
||||
assert(sizeof(arangeDescriptor.Address) >= HeaderData.AddrSize);
|
||||
|
||||
while (data.isValidOffset(*offset_ptr)) {
|
||||
arangeDescriptor.Address = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
|
||||
arangeDescriptor.Length = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
|
||||
|
||||
// Each set of tuples is terminated by a 0 for the address and 0
|
||||
// for the length.
|
||||
if (arangeDescriptor.Address || arangeDescriptor.Length)
|
||||
ArangeDescriptors.push_back(arangeDescriptor);
|
||||
else
|
||||
break; // We are done if we get a zero address and length
|
||||
}
|
||||
|
||||
return !ArangeDescriptors.empty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DWARFDebugArangeSet::dump(raw_ostream &OS) const {
|
||||
OS << format("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, ",
|
||||
HeaderData.Length, HeaderData.Version)
|
||||
<< format("cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n",
|
||||
HeaderData.CuOffset, HeaderData.AddrSize, HeaderData.SegSize);
|
||||
|
||||
const uint32_t hex_width = HeaderData.AddrSize * 2;
|
||||
for (const auto &Desc : ArangeDescriptors) {
|
||||
OS << format("[0x%*.*" PRIx64 " -", hex_width, hex_width, Desc.Address)
|
||||
<< format(" 0x%*.*" PRIx64 ")\n",
|
||||
hex_width, hex_width, Desc.getEndAddress());
|
||||
}
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
//===- DWARFDebugAranges.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/DWARFDebugAranges.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
|
||||
#include "llvm/Support/DataExtractor.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
void DWARFDebugAranges::extract(DataExtractor DebugArangesData) {
|
||||
if (!DebugArangesData.isValidOffset(0))
|
||||
return;
|
||||
uint32_t Offset = 0;
|
||||
DWARFDebugArangeSet Set;
|
||||
|
||||
while (Set.extract(DebugArangesData, &Offset)) {
|
||||
uint32_t CUOffset = Set.getCompileUnitDIEOffset();
|
||||
for (const auto &Desc : Set.descriptors()) {
|
||||
uint64_t LowPC = Desc.Address;
|
||||
uint64_t HighPC = Desc.getEndAddress();
|
||||
appendRange(CUOffset, LowPC, HighPC);
|
||||
}
|
||||
ParsedCUOffsets.insert(CUOffset);
|
||||
}
|
||||
}
|
||||
|
||||
void DWARFDebugAranges::generate(DWARFContext *CTX) {
|
||||
clear();
|
||||
if (!CTX)
|
||||
return;
|
||||
|
||||
// Extract aranges from .debug_aranges section.
|
||||
DataExtractor ArangesData(CTX->getDWARFObj().getARangeSection(),
|
||||
CTX->isLittleEndian(), 0);
|
||||
extract(ArangesData);
|
||||
|
||||
// Generate aranges from DIEs: even if .debug_aranges section is present,
|
||||
// it may describe only a small subset of compilation units, so we need to
|
||||
// manually build aranges for the rest of them.
|
||||
for (const auto &CU : CTX->compile_units()) {
|
||||
uint32_t CUOffset = CU->getOffset();
|
||||
if (ParsedCUOffsets.insert(CUOffset).second) {
|
||||
DWARFAddressRangesVector CURanges;
|
||||
CU->collectAddressRanges(CURanges);
|
||||
for (const auto &R : CURanges)
|
||||
appendRange(CUOffset, R.LowPC, R.HighPC);
|
||||
}
|
||||
}
|
||||
|
||||
construct();
|
||||
}
|
||||
|
||||
void DWARFDebugAranges::clear() {
|
||||
Endpoints.clear();
|
||||
Aranges.clear();
|
||||
ParsedCUOffsets.clear();
|
||||
}
|
||||
|
||||
void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC,
|
||||
uint64_t HighPC) {
|
||||
if (LowPC >= HighPC)
|
||||
return;
|
||||
Endpoints.emplace_back(LowPC, CUOffset, true);
|
||||
Endpoints.emplace_back(HighPC, CUOffset, false);
|
||||
}
|
||||
|
||||
void DWARFDebugAranges::construct() {
|
||||
std::multiset<uint32_t> ValidCUs; // Maintain the set of CUs describing
|
||||
// a current address range.
|
||||
std::sort(Endpoints.begin(), Endpoints.end());
|
||||
uint64_t PrevAddress = -1ULL;
|
||||
for (const auto &E : Endpoints) {
|
||||
if (PrevAddress < E.Address && !ValidCUs.empty()) {
|
||||
// If the address range between two endpoints is described by some
|
||||
// CU, first try to extend the last range in Aranges. If we can't
|
||||
// do it, start a new range.
|
||||
if (!Aranges.empty() && Aranges.back().HighPC() == PrevAddress &&
|
||||
ValidCUs.find(Aranges.back().CUOffset) != ValidCUs.end()) {
|
||||
Aranges.back().setHighPC(E.Address);
|
||||
} else {
|
||||
Aranges.emplace_back(PrevAddress, E.Address, *ValidCUs.begin());
|
||||
}
|
||||
}
|
||||
// Update the set of valid CUs.
|
||||
if (E.IsRangeStart) {
|
||||
ValidCUs.insert(E.CUOffset);
|
||||
} else {
|
||||
auto CUPos = ValidCUs.find(E.CUOffset);
|
||||
assert(CUPos != ValidCUs.end());
|
||||
ValidCUs.erase(CUPos);
|
||||
}
|
||||
PrevAddress = E.Address;
|
||||
}
|
||||
assert(ValidCUs.empty());
|
||||
|
||||
// Endpoints are not needed now.
|
||||
Endpoints.clear();
|
||||
Endpoints.shrink_to_fit();
|
||||
}
|
||||
|
||||
uint32_t DWARFDebugAranges::findAddress(uint64_t Address) const {
|
||||
if (!Aranges.empty()) {
|
||||
Range range(Address);
|
||||
RangeCollIterator begin = Aranges.begin();
|
||||
RangeCollIterator end = Aranges.end();
|
||||
RangeCollIterator pos =
|
||||
std::lower_bound(begin, end, range);
|
||||
|
||||
if (pos != end && pos->containsAddress(Address)) {
|
||||
return pos->CUOffset;
|
||||
} else if (pos != begin) {
|
||||
--pos;
|
||||
if (pos->containsAddress(Address))
|
||||
return pos->CUOffset;
|
||||
}
|
||||
}
|
||||
return -1U;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,70 +0,0 @@
|
||||
//===- DWARFDebugInfoEntry.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/DWARFDebugInfoEntry.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||
#include "llvm/Support/DataExtractor.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace dwarf;
|
||||
|
||||
bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U,
|
||||
uint32_t *OffsetPtr) {
|
||||
DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
|
||||
const uint32_t UEndOffset = U.getNextUnitOffset();
|
||||
return extractFast(U, OffsetPtr, DebugInfoData, UEndOffset, 0);
|
||||
}
|
||||
|
||||
bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint32_t *OffsetPtr,
|
||||
const DWARFDataExtractor &DebugInfoData,
|
||||
uint32_t UEndOffset, uint32_t D) {
|
||||
Offset = *OffsetPtr;
|
||||
Depth = D;
|
||||
if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset))
|
||||
return false;
|
||||
uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
|
||||
if (0 == AbbrCode) {
|
||||
// NULL debug tag entry.
|
||||
AbbrevDecl = nullptr;
|
||||
return true;
|
||||
}
|
||||
AbbrevDecl = U.getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
|
||||
if (nullptr == AbbrevDecl) {
|
||||
// Restore the original offset.
|
||||
*OffsetPtr = Offset;
|
||||
return false;
|
||||
}
|
||||
// See if all attributes in this DIE have fixed byte sizes. If so, we can
|
||||
// just add this size to the offset to skip to the next DIE.
|
||||
if (Optional<size_t> FixedSize = AbbrevDecl->getFixedAttributesByteSize(U)) {
|
||||
*OffsetPtr += *FixedSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Skip all data in the .debug_info for the attributes
|
||||
for (const auto &AttrSpec : AbbrevDecl->attributes()) {
|
||||
// Check if this attribute has a fixed byte size.
|
||||
if (auto FixedSize = AttrSpec.getByteSize(U)) {
|
||||
// Attribute byte size if fixed, just add the size to the offset.
|
||||
*OffsetPtr += *FixedSize;
|
||||
} else if (!DWARFFormValue::skipValue(AttrSpec.Form, DebugInfoData,
|
||||
OffsetPtr, U.getFormParams())) {
|
||||
// We failed to skip this attribute's value, restore the original offset
|
||||
// and return the failure status.
|
||||
*OffsetPtr = Offset;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
940
external/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
vendored
940
external/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
vendored
File diff suppressed because it is too large
Load Diff
224
external/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
vendored
224
external/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
vendored
@ -1,224 +0,0 @@
|
||||
//===- DWARFDebugLoc.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/DWARFDebugLoc.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
// When directly dumping the .debug_loc without a compile unit, we have to guess
|
||||
// at the DWARF version. This only affects DW_OP_call_ref, which is a rare
|
||||
// expression that LLVM doesn't produce. Guessing the wrong version means we
|
||||
// won't be able to pretty print expressions in DWARF2 binaries produced by
|
||||
// non-LLVM tools.
|
||||
static void dumpExpression(raw_ostream &OS, ArrayRef<char> Data,
|
||||
bool IsLittleEndian, unsigned AddressSize,
|
||||
const MCRegisterInfo *MRI) {
|
||||
DWARFDataExtractor Extractor(StringRef(Data.data(), Data.size()),
|
||||
IsLittleEndian, AddressSize);
|
||||
DWARFExpression(Extractor, AddressSize, dwarf::DWARF_VERSION).print(OS, MRI);
|
||||
}
|
||||
|
||||
void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, bool IsLittleEndian,
|
||||
unsigned AddressSize,
|
||||
const MCRegisterInfo *MRI,
|
||||
unsigned Indent) const {
|
||||
for (const Entry &E : Entries) {
|
||||
OS << '\n';
|
||||
OS.indent(Indent);
|
||||
OS << format("0x%016" PRIx64, E.Begin) << " - "
|
||||
<< format("0x%016" PRIx64, E.End) << ": ";
|
||||
|
||||
dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI);
|
||||
}
|
||||
}
|
||||
|
||||
DWARFDebugLoc::LocationList const *
|
||||
DWARFDebugLoc::getLocationListAtOffset(uint64_t Offset) const {
|
||||
auto It = std::lower_bound(
|
||||
Locations.begin(), Locations.end(), Offset,
|
||||
[](const LocationList &L, uint64_t Offset) { return L.Offset < Offset; });
|
||||
if (It != Locations.end() && It->Offset == Offset)
|
||||
return &(*It);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
|
||||
Optional<uint64_t> Offset) const {
|
||||
auto DumpLocationList = [&](const LocationList &L) {
|
||||
OS << format("0x%8.8x: ", L.Offset);
|
||||
L.dump(OS, IsLittleEndian, AddressSize, MRI, 12);
|
||||
OS << "\n\n";
|
||||
};
|
||||
|
||||
if (Offset) {
|
||||
if (auto *L = getLocationListAtOffset(*Offset))
|
||||
DumpLocationList(*L);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const LocationList &L : Locations) {
|
||||
DumpLocationList(L);
|
||||
}
|
||||
}
|
||||
|
||||
Optional<DWARFDebugLoc::LocationList>
|
||||
DWARFDebugLoc::parseOneLocationList(DWARFDataExtractor Data, unsigned *Offset) {
|
||||
LocationList LL;
|
||||
LL.Offset = *Offset;
|
||||
|
||||
// 2.6.2 Location Lists
|
||||
// A location list entry consists of:
|
||||
while (true) {
|
||||
Entry E;
|
||||
if (!Data.isValidOffsetForDataOfSize(*Offset, 2 * Data.getAddressSize())) {
|
||||
llvm::errs() << "Location list overflows the debug_loc section.\n";
|
||||
return None;
|
||||
}
|
||||
|
||||
// 1. A beginning address offset. ...
|
||||
E.Begin = Data.getRelocatedAddress(Offset);
|
||||
|
||||
// 2. An ending address offset. ...
|
||||
E.End = Data.getRelocatedAddress(Offset);
|
||||
|
||||
// The end of any given location list is marked by an end of list entry,
|
||||
// which consists of a 0 for the beginning address offset and a 0 for the
|
||||
// ending address offset.
|
||||
if (E.Begin == 0 && E.End == 0)
|
||||
return LL;
|
||||
|
||||
if (!Data.isValidOffsetForDataOfSize(*Offset, 2)) {
|
||||
llvm::errs() << "Location list overflows the debug_loc section.\n";
|
||||
return None;
|
||||
}
|
||||
|
||||
unsigned Bytes = Data.getU16(Offset);
|
||||
if (!Data.isValidOffsetForDataOfSize(*Offset, Bytes)) {
|
||||
llvm::errs() << "Location list overflows the debug_loc section.\n";
|
||||
return None;
|
||||
}
|
||||
// A single location description describing the location of the object...
|
||||
StringRef str = Data.getData().substr(*Offset, Bytes);
|
||||
*Offset += Bytes;
|
||||
E.Loc.reserve(str.size());
|
||||
std::copy(str.begin(), str.end(), std::back_inserter(E.Loc));
|
||||
LL.Entries.push_back(std::move(E));
|
||||
}
|
||||
}
|
||||
|
||||
void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
|
||||
IsLittleEndian = data.isLittleEndian();
|
||||
AddressSize = data.getAddressSize();
|
||||
|
||||
uint32_t Offset = 0;
|
||||
while (data.isValidOffset(Offset + data.getAddressSize() - 1)) {
|
||||
if (auto LL = parseOneLocationList(data, &Offset))
|
||||
Locations.push_back(std::move(*LL));
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (data.isValidOffset(Offset))
|
||||
errs() << "error: failed to consume entire .debug_loc section\n";
|
||||
}
|
||||
|
||||
Optional<DWARFDebugLocDWO::LocationList>
|
||||
DWARFDebugLocDWO::parseOneLocationList(DataExtractor Data, unsigned *Offset) {
|
||||
LocationList LL;
|
||||
LL.Offset = *Offset;
|
||||
|
||||
// dwarf::DW_LLE_end_of_list_entry is 0 and indicates the end of the list.
|
||||
while (auto Kind =
|
||||
static_cast<dwarf::LocationListEntry>(Data.getU8(Offset))) {
|
||||
if (Kind != dwarf::DW_LLE_startx_length) {
|
||||
llvm::errs() << "error: dumping support for LLE of kind " << (int)Kind
|
||||
<< " not implemented\n";
|
||||
return None;
|
||||
}
|
||||
|
||||
Entry E;
|
||||
E.Start = Data.getULEB128(Offset);
|
||||
E.Length = Data.getU32(Offset);
|
||||
|
||||
unsigned Bytes = Data.getU16(Offset);
|
||||
// A single location description describing the location of the object...
|
||||
StringRef str = Data.getData().substr(*Offset, Bytes);
|
||||
*Offset += Bytes;
|
||||
E.Loc.resize(str.size());
|
||||
std::copy(str.begin(), str.end(), E.Loc.begin());
|
||||
|
||||
LL.Entries.push_back(std::move(E));
|
||||
}
|
||||
return LL;
|
||||
}
|
||||
|
||||
void DWARFDebugLocDWO::parse(DataExtractor data) {
|
||||
IsLittleEndian = data.isLittleEndian();
|
||||
AddressSize = data.getAddressSize();
|
||||
|
||||
uint32_t Offset = 0;
|
||||
while (data.isValidOffset(Offset)) {
|
||||
if (auto LL = parseOneLocationList(data, &Offset))
|
||||
Locations.push_back(std::move(*LL));
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DWARFDebugLocDWO::LocationList const *
|
||||
DWARFDebugLocDWO::getLocationListAtOffset(uint64_t Offset) const {
|
||||
auto It = std::lower_bound(
|
||||
Locations.begin(), Locations.end(), Offset,
|
||||
[](const LocationList &L, uint64_t Offset) { return L.Offset < Offset; });
|
||||
if (It != Locations.end() && It->Offset == Offset)
|
||||
return &(*It);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DWARFDebugLocDWO::LocationList::dump(raw_ostream &OS, bool IsLittleEndian,
|
||||
unsigned AddressSize,
|
||||
const MCRegisterInfo *MRI,
|
||||
unsigned Indent) const {
|
||||
for (const Entry &E : Entries) {
|
||||
OS << '\n';
|
||||
OS.indent(Indent);
|
||||
OS << "Addr idx " << E.Start << " (w/ length " << E.Length << "): ";
|
||||
dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI);
|
||||
}
|
||||
}
|
||||
|
||||
void DWARFDebugLocDWO::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
|
||||
Optional<uint64_t> Offset) const {
|
||||
auto DumpLocationList = [&](const LocationList &L) {
|
||||
OS << format("0x%8.8x: ", L.Offset);
|
||||
L.dump(OS, IsLittleEndian, AddressSize, MRI, /*Indent=*/12);
|
||||
OS << "\n\n";
|
||||
};
|
||||
|
||||
if (Offset) {
|
||||
if (auto *L = getLocationListAtOffset(*Offset))
|
||||
DumpLocationList(*L);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const LocationList &L : Locations) {
|
||||
DumpLocationList(L);
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
//===- DWARFDebugMacro.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/DWARFDebugMacro.h"
|
||||
#include "SyntaxHighlighting.h"
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstdint>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace dwarf;
|
||||
using namespace syntax;
|
||||
|
||||
void DWARFDebugMacro::dump(raw_ostream &OS) const {
|
||||
unsigned IndLevel = 0;
|
||||
for (const Entry &E : Macros) {
|
||||
// There should not be DW_MACINFO_end_file when IndLevel is Zero. However,
|
||||
// this check handles the case of corrupted ".debug_macinfo" section.
|
||||
if (IndLevel > 0)
|
||||
IndLevel -= (E.Type == DW_MACINFO_end_file);
|
||||
// Print indentation.
|
||||
for (unsigned I = 0; I < IndLevel; I++)
|
||||
OS << " ";
|
||||
IndLevel += (E.Type == DW_MACINFO_start_file);
|
||||
|
||||
WithColor(OS, syntax::Macro).get() << MacinfoString(E.Type);
|
||||
switch (E.Type) {
|
||||
default:
|
||||
// Got a corrupted ".debug_macinfo" section (invalid macinfo type).
|
||||
break;
|
||||
case DW_MACINFO_define:
|
||||
case DW_MACINFO_undef:
|
||||
OS << " - lineno: " << E.Line;
|
||||
OS << " macro: " << E.MacroStr;
|
||||
break;
|
||||
case DW_MACINFO_start_file:
|
||||
OS << " - lineno: " << E.Line;
|
||||
OS << " filenum: " << E.File;
|
||||
break;
|
||||
case DW_MACINFO_end_file:
|
||||
break;
|
||||
case DW_MACINFO_vendor_ext:
|
||||
OS << " - constant: " << E.ExtConstant;
|
||||
OS << " string: " << E.ExtStr;
|
||||
break;
|
||||
}
|
||||
OS << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void DWARFDebugMacro::parse(DataExtractor data) {
|
||||
uint32_t Offset = 0;
|
||||
while (data.isValidOffset(Offset)) {
|
||||
// A macro list entry consists of:
|
||||
Entry E;
|
||||
// 1. Macinfo type
|
||||
E.Type = data.getULEB128(&Offset);
|
||||
|
||||
if (E.Type == 0) {
|
||||
// Reached end of ".debug_macinfo" section.
|
||||
return;
|
||||
}
|
||||
|
||||
switch (E.Type) {
|
||||
default:
|
||||
// Got a corrupted ".debug_macinfo" section (invalid macinfo type).
|
||||
// Push the corrupted entry to the list and halt parsing.
|
||||
E.Type = DW_MACINFO_invalid;
|
||||
Macros.push_back(E);
|
||||
return;
|
||||
case DW_MACINFO_define:
|
||||
case DW_MACINFO_undef:
|
||||
// 2. Source line
|
||||
E.Line = data.getULEB128(&Offset);
|
||||
// 3. Macro string
|
||||
E.MacroStr = data.getCStr(&Offset);
|
||||
break;
|
||||
case DW_MACINFO_start_file:
|
||||
// 2. Source line
|
||||
E.Line = data.getULEB128(&Offset);
|
||||
// 3. Source file id
|
||||
E.File = data.getULEB128(&Offset);
|
||||
break;
|
||||
case DW_MACINFO_end_file:
|
||||
break;
|
||||
case DW_MACINFO_vendor_ext:
|
||||
// 2. Vendor extension constant
|
||||
E.ExtConstant = data.getULEB128(&Offset);
|
||||
// 3. Vendor extension string
|
||||
E.ExtStr = data.getCStr(&Offset);
|
||||
break;
|
||||
}
|
||||
|
||||
Macros.push_back(E);
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
//===- DWARFDebugPubTable.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/DWARFDebugPubTable.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
#include "llvm/Support/DataExtractor.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstdint>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace dwarf;
|
||||
|
||||
DWARFDebugPubTable::DWARFDebugPubTable(StringRef Data, bool LittleEndian,
|
||||
bool GnuStyle)
|
||||
: GnuStyle(GnuStyle) {
|
||||
DataExtractor PubNames(Data, LittleEndian, 0);
|
||||
uint32_t Offset = 0;
|
||||
while (PubNames.isValidOffset(Offset)) {
|
||||
Sets.push_back({});
|
||||
Set &SetData = Sets.back();
|
||||
|
||||
SetData.Length = PubNames.getU32(&Offset);
|
||||
SetData.Version = PubNames.getU16(&Offset);
|
||||
SetData.Offset = PubNames.getU32(&Offset);
|
||||
SetData.Size = PubNames.getU32(&Offset);
|
||||
|
||||
while (Offset < Data.size()) {
|
||||
uint32_t DieRef = PubNames.getU32(&Offset);
|
||||
if (DieRef == 0)
|
||||
break;
|
||||
uint8_t IndexEntryValue = GnuStyle ? PubNames.getU8(&Offset) : 0;
|
||||
const char *Name = PubNames.getCStr(&Offset);
|
||||
SetData.Entries.push_back(
|
||||
{DieRef, PubIndexEntryDescriptor(IndexEntryValue), Name});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DWARFDebugPubTable::dump(raw_ostream &OS) const {
|
||||
for (const Set &S : Sets) {
|
||||
OS << "length = " << format("0x%08x", S.Length);
|
||||
OS << " version = " << format("0x%04x", S.Version);
|
||||
OS << " unit_offset = " << format("0x%08x", S.Offset);
|
||||
OS << " unit_size = " << format("0x%08x", S.Size) << '\n';
|
||||
OS << (GnuStyle ? "Offset Linkage Kind Name\n"
|
||||
: "Offset Name\n");
|
||||
|
||||
for (const Entry &E : S.Entries) {
|
||||
OS << format("0x%8.8x ", E.SecOffset);
|
||||
if (GnuStyle) {
|
||||
StringRef EntryLinkage =
|
||||
GDBIndexEntryLinkageString(E.Descriptor.Linkage);
|
||||
StringRef EntryKind = dwarf::GDBIndexEntryKindString(E.Descriptor.Kind);
|
||||
OS << format("%-8s", EntryLinkage.data()) << ' '
|
||||
<< format("%-8s", EntryKind.data()) << ' ';
|
||||
}
|
||||
OS << '\"' << E.Name << "\"\n";
|
||||
}
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
//===- DWARFDebugRangesList.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/DWARFDebugRangeList.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cinttypes>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
raw_ostream &llvm::operator<<(raw_ostream &OS, const DWARFAddressRange &R) {
|
||||
return OS << format("[0x%16.16" PRIx64 ", 0x%16.16" PRIx64 ")", R.LowPC,
|
||||
R.HighPC);
|
||||
}
|
||||
|
||||
void DWARFDebugRangeList::clear() {
|
||||
Offset = -1U;
|
||||
AddressSize = 0;
|
||||
Entries.clear();
|
||||
}
|
||||
|
||||
bool DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
|
||||
uint32_t *offset_ptr) {
|
||||
clear();
|
||||
if (!data.isValidOffset(*offset_ptr))
|
||||
return false;
|
||||
AddressSize = data.getAddressSize();
|
||||
if (AddressSize != 4 && AddressSize != 8)
|
||||
return false;
|
||||
Offset = *offset_ptr;
|
||||
while (true) {
|
||||
RangeListEntry Entry;
|
||||
Entry.SectionIndex = -1ULL;
|
||||
|
||||
uint32_t prev_offset = *offset_ptr;
|
||||
Entry.StartAddress = data.getRelocatedAddress(offset_ptr);
|
||||
Entry.EndAddress =
|
||||
data.getRelocatedAddress(offset_ptr, &Entry.SectionIndex);
|
||||
|
||||
// Check that both values were extracted correctly.
|
||||
if (*offset_ptr != prev_offset + 2 * AddressSize) {
|
||||
clear();
|
||||
return false;
|
||||
}
|
||||
if (Entry.isEndOfListEntry())
|
||||
break;
|
||||
Entries.push_back(Entry);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DWARFDebugRangeList::dump(raw_ostream &OS) const {
|
||||
for (const RangeListEntry &RLE : Entries) {
|
||||
const char *format_str = (AddressSize == 4
|
||||
? "%08x %08" PRIx64 " %08" PRIx64 "\n"
|
||||
: "%08x %016" PRIx64 " %016" PRIx64 "\n");
|
||||
OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress);
|
||||
}
|
||||
OS << format("%08x <End of list>\n", Offset);
|
||||
}
|
||||
|
||||
DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
|
||||
llvm::Optional<BaseAddress> BaseAddr) const {
|
||||
DWARFAddressRangesVector Res;
|
||||
for (const RangeListEntry &RLE : Entries) {
|
||||
if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
|
||||
BaseAddr = {RLE.EndAddress, RLE.SectionIndex};
|
||||
continue;
|
||||
}
|
||||
|
||||
DWARFAddressRange E;
|
||||
E.LowPC = RLE.StartAddress;
|
||||
E.HighPC = RLE.EndAddress;
|
||||
E.SectionIndex = RLE.SectionIndex;
|
||||
// Base address of a range list entry is determined by the closest preceding
|
||||
// base address selection entry in the same range list. It defaults to the
|
||||
// base address of the compilation unit if there is no such entry.
|
||||
if (BaseAddr) {
|
||||
E.LowPC += BaseAddr->Address;
|
||||
E.HighPC += BaseAddr->Address;
|
||||
if (E.SectionIndex == -1ULL)
|
||||
E.SectionIndex = BaseAddr->SectionIndex;
|
||||
}
|
||||
Res.push_back(E);
|
||||
}
|
||||
return Res;
|
||||
}
|
578
external/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
vendored
578
external/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
vendored
File diff suppressed because it is too large
Load Diff
@ -1,274 +0,0 @@
|
||||
//===-- DWARFExpression.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/DWARFExpression.h"
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace dwarf;
|
||||
|
||||
namespace llvm {
|
||||
|
||||
typedef std::vector<DWARFExpression::Operation::Description> DescVector;
|
||||
|
||||
static DescVector getDescriptions() {
|
||||
DescVector Descriptions;
|
||||
typedef DWARFExpression::Operation Op;
|
||||
typedef Op::Description Desc;
|
||||
|
||||
Descriptions.resize(0xff);
|
||||
Descriptions[DW_OP_addr] = Desc(Op::Dwarf2, Op::SizeAddr);
|
||||
Descriptions[DW_OP_deref] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_const1u] = Desc(Op::Dwarf2, Op::Size1);
|
||||
Descriptions[DW_OP_const1s] = Desc(Op::Dwarf2, Op::SignedSize1);
|
||||
Descriptions[DW_OP_const2u] = Desc(Op::Dwarf2, Op::Size2);
|
||||
Descriptions[DW_OP_const2s] = Desc(Op::Dwarf2, Op::SignedSize2);
|
||||
Descriptions[DW_OP_const4u] = Desc(Op::Dwarf2, Op::Size4);
|
||||
Descriptions[DW_OP_const4s] = Desc(Op::Dwarf2, Op::SignedSize4);
|
||||
Descriptions[DW_OP_const8u] = Desc(Op::Dwarf2, Op::Size8);
|
||||
Descriptions[DW_OP_const8s] = Desc(Op::Dwarf2, Op::SignedSize8);
|
||||
Descriptions[DW_OP_constu] = Desc(Op::Dwarf2, Op::SizeLEB);
|
||||
Descriptions[DW_OP_consts] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
|
||||
Descriptions[DW_OP_dup] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_drop] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_over] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_pick] = Desc(Op::Dwarf2, Op::Size1);
|
||||
Descriptions[DW_OP_swap] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_rot] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_xderef] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_abs] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_and] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_div] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_minus] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_mod] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_mul] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_neg] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_not] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_or] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_plus] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_plus_uconst] = Desc(Op::Dwarf2, Op::SizeLEB);
|
||||
Descriptions[DW_OP_shl] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_shr] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_shra] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_xor] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2);
|
||||
Descriptions[DW_OP_bra] = Desc(Op::Dwarf2, Op::SignedSize2);
|
||||
Descriptions[DW_OP_eq] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_ge] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_gt] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_le] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_lt] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_ne] = Desc(Op::Dwarf2);
|
||||
for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA)
|
||||
Descriptions[LA] = Desc(Op::Dwarf2);
|
||||
for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA)
|
||||
Descriptions[LA] = Desc(Op::Dwarf2);
|
||||
for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA)
|
||||
Descriptions[LA] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
|
||||
Descriptions[DW_OP_regx] = Desc(Op::Dwarf2, Op::SizeLEB);
|
||||
Descriptions[DW_OP_fbreg] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
|
||||
Descriptions[DW_OP_bregx] = Desc(Op::Dwarf2, Op::SizeLEB, Op::SignedSizeLEB);
|
||||
Descriptions[DW_OP_piece] = Desc(Op::Dwarf2, Op::SizeLEB);
|
||||
Descriptions[DW_OP_deref_size] = Desc(Op::Dwarf2, Op::Size1);
|
||||
Descriptions[DW_OP_xderef_size] = Desc(Op::Dwarf2, Op::Size1);
|
||||
Descriptions[DW_OP_nop] = Desc(Op::Dwarf2);
|
||||
Descriptions[DW_OP_push_object_address] = Desc(Op::Dwarf3);
|
||||
Descriptions[DW_OP_call2] = Desc(Op::Dwarf3, Op::Size2);
|
||||
Descriptions[DW_OP_call4] = Desc(Op::Dwarf3, Op::Size4);
|
||||
Descriptions[DW_OP_call_ref] = Desc(Op::Dwarf3, Op::SizeRefAddr);
|
||||
Descriptions[DW_OP_form_tls_address] = Desc(Op::Dwarf3);
|
||||
Descriptions[DW_OP_call_frame_cfa] = Desc(Op::Dwarf3);
|
||||
Descriptions[DW_OP_bit_piece] = Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeLEB);
|
||||
Descriptions[DW_OP_implicit_value] =
|
||||
Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock);
|
||||
Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3);
|
||||
Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3);
|
||||
Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);
|
||||
Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB);
|
||||
return Descriptions;
|
||||
}
|
||||
|
||||
static DWARFExpression::Operation::Description getOpDesc(unsigned OpCode) {
|
||||
// FIXME: Make this constexpr once all compilers are smart enough to do it.
|
||||
static DescVector Descriptions = getDescriptions();
|
||||
// Handle possible corrupted or unsupported operation.
|
||||
if (OpCode >= Descriptions.size())
|
||||
return {};
|
||||
return Descriptions[OpCode];
|
||||
}
|
||||
|
||||
static uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) {
|
||||
return (Version == 2) ? AddrSize : 4;
|
||||
}
|
||||
|
||||
bool DWARFExpression::Operation::extract(DataExtractor Data, uint16_t Version,
|
||||
uint8_t AddressSize, uint32_t Offset) {
|
||||
Opcode = Data.getU8(&Offset);
|
||||
|
||||
Desc = getOpDesc(Opcode);
|
||||
if (Desc.Version == Operation::DwarfNA) {
|
||||
EndOffset = Offset;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned Operand = 0; Operand < 2; ++Operand) {
|
||||
unsigned Size = Desc.Op[Operand];
|
||||
unsigned Signed = Size & Operation::SignBit;
|
||||
|
||||
if (Size == Operation::SizeNA)
|
||||
break;
|
||||
|
||||
switch (Size & ~Operation::SignBit) {
|
||||
case Operation::Size1:
|
||||
Operands[Operand] = Data.getU8(&Offset);
|
||||
if (Signed)
|
||||
Operands[Operand] = (int8_t)Operands[Operand];
|
||||
break;
|
||||
case Operation::Size2:
|
||||
Operands[Operand] = Data.getU16(&Offset);
|
||||
if (Signed)
|
||||
Operands[Operand] = (int16_t)Operands[Operand];
|
||||
break;
|
||||
case Operation::Size4:
|
||||
Operands[Operand] = Data.getU32(&Offset);
|
||||
if (Signed)
|
||||
Operands[Operand] = (int32_t)Operands[Operand];
|
||||
break;
|
||||
case Operation::Size8:
|
||||
Operands[Operand] = Data.getU64(&Offset);
|
||||
break;
|
||||
case Operation::SizeAddr:
|
||||
if (AddressSize == 8) {
|
||||
Operands[Operand] = Data.getU64(&Offset);
|
||||
} else {
|
||||
assert(AddressSize == 4);
|
||||
Operands[Operand] = Data.getU32(&Offset);
|
||||
}
|
||||
break;
|
||||
case Operation::SizeRefAddr:
|
||||
if (getRefAddrSize(AddressSize, Version) == 8) {
|
||||
Operands[Operand] = Data.getU64(&Offset);
|
||||
} else {
|
||||
assert(getRefAddrSize(AddressSize, Version) == 4);
|
||||
Operands[Operand] = Data.getU32(&Offset);
|
||||
}
|
||||
break;
|
||||
case Operation::SizeLEB:
|
||||
if (Signed)
|
||||
Operands[Operand] = Data.getSLEB128(&Offset);
|
||||
else
|
||||
Operands[Operand] = Data.getULEB128(&Offset);
|
||||
break;
|
||||
case Operation::SizeBlock:
|
||||
// We need a size, so this cannot be the first operand
|
||||
if (Operand == 0)
|
||||
return false;
|
||||
// Store the offset of the block as the value.
|
||||
Operands[Operand] = Offset;
|
||||
Offset += Operands[Operand - 1];
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unknown DWARFExpression Op size");
|
||||
}
|
||||
}
|
||||
|
||||
EndOffset = Offset;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool prettyPrintRegisterOp(raw_ostream &OS, uint8_t Opcode,
|
||||
uint64_t Operands[2],
|
||||
const MCRegisterInfo *MRI, bool isEH) {
|
||||
if (!MRI)
|
||||
return false;
|
||||
|
||||
uint64_t DwarfRegNum;
|
||||
unsigned OpNum = 0;
|
||||
|
||||
if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx)
|
||||
DwarfRegNum = Operands[OpNum++];
|
||||
else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
|
||||
DwarfRegNum = Opcode - DW_OP_breg0;
|
||||
else
|
||||
DwarfRegNum = Opcode - DW_OP_reg0;
|
||||
|
||||
int LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH);
|
||||
if (LLVMRegNum >= 0) {
|
||||
if (const char *RegName = MRI->getName(LLVMRegNum)) {
|
||||
if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
|
||||
Opcode == DW_OP_bregx)
|
||||
OS << format(" %s%+" PRId64, RegName, Operands[OpNum]);
|
||||
else
|
||||
OS << ' ' << RegName;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DWARFExpression::Operation::print(raw_ostream &OS,
|
||||
const DWARFExpression *Expr,
|
||||
const MCRegisterInfo *RegInfo,
|
||||
bool isEH) {
|
||||
if (Error) {
|
||||
OS << "<decoding error>";
|
||||
return false;
|
||||
}
|
||||
|
||||
StringRef Name = OperationEncodingString(Opcode);
|
||||
assert(!Name.empty() && "DW_OP has no name!");
|
||||
OS << Name;
|
||||
|
||||
if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
|
||||
(Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
|
||||
Opcode == DW_OP_bregx || Opcode == DW_OP_regx)
|
||||
if (prettyPrintRegisterOp(OS, Opcode, Operands, RegInfo, isEH))
|
||||
return true;
|
||||
|
||||
for (unsigned Operand = 0; Operand < 2; ++Operand) {
|
||||
unsigned Size = Desc.Op[Operand];
|
||||
unsigned Signed = Size & Operation::SignBit;
|
||||
|
||||
if (Size == Operation::SizeNA)
|
||||
break;
|
||||
|
||||
if (Size == Operation::SizeBlock) {
|
||||
uint32_t Offset = Operands[Operand];
|
||||
for (unsigned i = 0; i < Operands[Operand - 1]; ++i)
|
||||
OS << format(" 0x%02x", Expr->Data.getU8(&Offset));
|
||||
} else {
|
||||
if (Signed)
|
||||
OS << format(" %+" PRId64, (int64_t)Operands[Operand]);
|
||||
else
|
||||
OS << format(" 0x%" PRIx64, Operands[Operand]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo) {
|
||||
for (auto &Op : *this) {
|
||||
if (!Op.print(OS, this, RegInfo, /* isEH */ false)) {
|
||||
uint32_t FailOffset = Op.getEndOffset();
|
||||
while (FailOffset < Data.getData().size())
|
||||
OS << format(" %02x", Data.getU8(&FailOffset));
|
||||
return;
|
||||
}
|
||||
if (Op.getEndOffset() < Data.getData().size())
|
||||
OS << ", ";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace llvm
|
679
external/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
vendored
679
external/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
vendored
File diff suppressed because it is too large
Load Diff
183
external/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
vendored
183
external/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
vendored
@ -1,183 +0,0 @@
|
||||
//===- DWARFGdbIndex.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/DWARFGdbIndex.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cinttypes>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
// .gdb_index section format reference:
|
||||
// https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
|
||||
|
||||
void DWARFGdbIndex::dumpCUList(raw_ostream &OS) const {
|
||||
OS << format("\n CU list offset = 0x%x, has %" PRId64 " entries:",
|
||||
CuListOffset, (uint64_t)CuList.size())
|
||||
<< '\n';
|
||||
uint32_t I = 0;
|
||||
for (const CompUnitEntry &CU : CuList)
|
||||
OS << format(" %d: Offset = 0x%llx, Length = 0x%llx\n", I++, CU.Offset,
|
||||
CU.Length);
|
||||
}
|
||||
|
||||
void DWARFGdbIndex::dumpAddressArea(raw_ostream &OS) const {
|
||||
OS << format("\n Address area offset = 0x%x, has %" PRId64 " entries:",
|
||||
AddressAreaOffset, (uint64_t)AddressArea.size())
|
||||
<< '\n';
|
||||
for (const AddressEntry &Addr : AddressArea)
|
||||
OS << format(
|
||||
" Low/High address = [0x%llx, 0x%llx) (Size: 0x%llx), CU id = %d\n",
|
||||
Addr.LowAddress, Addr.HighAddress, Addr.HighAddress - Addr.LowAddress,
|
||||
Addr.CuIndex);
|
||||
}
|
||||
|
||||
void DWARFGdbIndex::dumpSymbolTable(raw_ostream &OS) const {
|
||||
OS << format("\n Symbol table offset = 0x%x, size = %" PRId64
|
||||
", filled slots:",
|
||||
SymbolTableOffset, (uint64_t)SymbolTable.size())
|
||||
<< '\n';
|
||||
uint32_t I = -1;
|
||||
for (const SymTableEntry &E : SymbolTable) {
|
||||
++I;
|
||||
if (!E.NameOffset && !E.VecOffset)
|
||||
continue;
|
||||
|
||||
OS << format(" %d: Name offset = 0x%x, CU vector offset = 0x%x\n", I,
|
||||
E.NameOffset, E.VecOffset);
|
||||
|
||||
StringRef Name = ConstantPoolStrings.substr(
|
||||
ConstantPoolOffset - StringPoolOffset + E.NameOffset);
|
||||
|
||||
auto CuVector = std::find_if(
|
||||
ConstantPoolVectors.begin(), ConstantPoolVectors.end(),
|
||||
[&](const std::pair<uint32_t, SmallVector<uint32_t, 0>> &V) {
|
||||
return V.first == E.VecOffset;
|
||||
});
|
||||
assert(CuVector != ConstantPoolVectors.end() && "Invalid symbol table");
|
||||
uint32_t CuVectorId = CuVector - ConstantPoolVectors.begin();
|
||||
OS << format(" String name: %s, CU vector index: %d\n", Name.data(),
|
||||
CuVectorId);
|
||||
}
|
||||
}
|
||||
|
||||
void DWARFGdbIndex::dumpConstantPool(raw_ostream &OS) const {
|
||||
OS << format("\n Constant pool offset = 0x%x, has %" PRId64 " CU vectors:",
|
||||
ConstantPoolOffset, (uint64_t)ConstantPoolVectors.size());
|
||||
uint32_t I = 0;
|
||||
for (const auto &V : ConstantPoolVectors) {
|
||||
OS << format("\n %d(0x%x): ", I++, V.first);
|
||||
for (uint32_t Val : V.second)
|
||||
OS << format("0x%x ", Val);
|
||||
}
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
void DWARFGdbIndex::dump(raw_ostream &OS) {
|
||||
if (HasError) {
|
||||
OS << "\n<error parsing>\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasContent) {
|
||||
OS << " Version = " << Version << '\n';
|
||||
dumpCUList(OS);
|
||||
dumpAddressArea(OS);
|
||||
dumpSymbolTable(OS);
|
||||
dumpConstantPool(OS);
|
||||
}
|
||||
}
|
||||
|
||||
bool DWARFGdbIndex::parseImpl(DataExtractor Data) {
|
||||
uint32_t Offset = 0;
|
||||
|
||||
// Only version 7 is supported at this moment.
|
||||
Version = Data.getU32(&Offset);
|
||||
if (Version != 7)
|
||||
return false;
|
||||
|
||||
CuListOffset = Data.getU32(&Offset);
|
||||
uint32_t CuTypesOffset = Data.getU32(&Offset);
|
||||
AddressAreaOffset = Data.getU32(&Offset);
|
||||
SymbolTableOffset = Data.getU32(&Offset);
|
||||
ConstantPoolOffset = Data.getU32(&Offset);
|
||||
|
||||
if (Offset != CuListOffset)
|
||||
return false;
|
||||
|
||||
uint32_t CuListSize = (CuTypesOffset - CuListOffset) / 16;
|
||||
CuList.reserve(CuListSize);
|
||||
for (uint32_t i = 0; i < CuListSize; ++i) {
|
||||
uint64_t CuOffset = Data.getU64(&Offset);
|
||||
uint64_t CuLength = Data.getU64(&Offset);
|
||||
CuList.push_back({CuOffset, CuLength});
|
||||
}
|
||||
|
||||
// CU Types are no longer needed as DWARF skeleton type units never made it
|
||||
// into the standard.
|
||||
uint32_t CuTypesListSize = (AddressAreaOffset - CuTypesOffset) / 24;
|
||||
if (CuTypesListSize != 0)
|
||||
return false;
|
||||
|
||||
uint32_t AddressAreaSize = (SymbolTableOffset - AddressAreaOffset) / 20;
|
||||
AddressArea.reserve(AddressAreaSize);
|
||||
for (uint32_t i = 0; i < AddressAreaSize; ++i) {
|
||||
uint64_t LowAddress = Data.getU64(&Offset);
|
||||
uint64_t HighAddress = Data.getU64(&Offset);
|
||||
uint32_t CuIndex = Data.getU32(&Offset);
|
||||
AddressArea.push_back({LowAddress, HighAddress, CuIndex});
|
||||
}
|
||||
|
||||
// The symbol table. This is an open addressed hash table. The size of the
|
||||
// hash table is always a power of 2.
|
||||
// Each slot in the hash table consists of a pair of offset_type values. The
|
||||
// first value is the offset of the symbol's name in the constant pool. The
|
||||
// second value is the offset of the CU vector in the constant pool.
|
||||
// If both values are 0, then this slot in the hash table is empty. This is ok
|
||||
// because while 0 is a valid constant pool index, it cannot be a valid index
|
||||
// for both a string and a CU vector.
|
||||
uint32_t SymTableSize = (ConstantPoolOffset - SymbolTableOffset) / 8;
|
||||
SymbolTable.reserve(SymTableSize);
|
||||
uint32_t CuVectorsTotal = 0;
|
||||
for (uint32_t i = 0; i < SymTableSize; ++i) {
|
||||
uint32_t NameOffset = Data.getU32(&Offset);
|
||||
uint32_t CuVecOffset = Data.getU32(&Offset);
|
||||
SymbolTable.push_back({NameOffset, CuVecOffset});
|
||||
if (NameOffset || CuVecOffset)
|
||||
++CuVectorsTotal;
|
||||
}
|
||||
|
||||
// The constant pool. CU vectors are stored first, followed by strings.
|
||||
// The first value is the number of CU indices in the vector. Each subsequent
|
||||
// value is the index and symbol attributes of a CU in the CU list.
|
||||
for (uint32_t i = 0; i < CuVectorsTotal; ++i) {
|
||||
ConstantPoolVectors.emplace_back(0, SmallVector<uint32_t, 0>());
|
||||
auto &Vec = ConstantPoolVectors.back();
|
||||
Vec.first = Offset - ConstantPoolOffset;
|
||||
|
||||
uint32_t Num = Data.getU32(&Offset);
|
||||
for (uint32_t j = 0; j < Num; ++j)
|
||||
Vec.second.push_back(Data.getU32(&Offset));
|
||||
}
|
||||
|
||||
ConstantPoolStrings = Data.getData().drop_front(Offset);
|
||||
StringPoolOffset = Offset;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DWARFGdbIndex::parse(DataExtractor Data) {
|
||||
HasContent = !Data.getData().empty();
|
||||
HasError = HasContent && !parseImpl(Data);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user