Reapply "[NFC][DebugInfo][DWARF] Create new low-level dwarf library (#… (#145959) This reapplies cbf781f0bdf2f680abbe784faedeefd6f84c246e, with fixes for the shared-library build and the unconventional sanitizer-runtime build. Original Description: This is the culmination of a series of changes described in [1]. Although somewhat large by line count, it is almost entirely mechanical, creating a new library in DebugInfo/DWARF/LowLevel. This new library has very minimal dependencies, allowing it to be used from more places than the normal DebugInfo/DWARF library--in particular from MC. 1. https://discourse.llvm.org/t/rfc-debuginfo-dwarf-refactor-into-to-lower-and-higher-level-libraries/86665/2
This commit is contained in:
parent
a4be46e0e5
commit
23f1ba3ee4
@ -20,8 +20,8 @@
|
|||||||
#include "llvm/CodeGen/DIE.h"
|
#include "llvm/CodeGen/DIE.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
|
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/Allocator.h"
|
#include "llvm/Support/Allocator.h"
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
set(LLVM_LINK_COMPONENTS
|
set(LLVM_LINK_COMPONENTS
|
||||||
DebugInfoDWARF
|
DebugInfoDWARF
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
Demangle
|
Demangle
|
||||||
MC
|
MC
|
||||||
MCDisassembler
|
MCDisassembler
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
#include "llvm/CodeGen/DIE.h"
|
#include "llvm/CodeGen/DIE.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
|
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/Casting.h"
|
#include "llvm/Support/Casting.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
#include "bolt/Core/DebugNames.h"
|
#include "bolt/Core/DebugNames.h"
|
||||||
#include "bolt/Core/BinaryContext.h"
|
#include "bolt/Core/BinaryContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/EndianStream.h"
|
#include "llvm/Support/EndianStream.h"
|
||||||
#include "llvm/Support/LEB128.h"
|
#include "llvm/Support/LEB128.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
set(LLVM_LINK_COMPONENTS
|
set(LLVM_LINK_COMPONENTS
|
||||||
Core
|
Core
|
||||||
DebugInfoDWARF
|
DebugInfoDWARF
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
JITLink
|
JITLink
|
||||||
MC
|
MC
|
||||||
Object
|
Object
|
||||||
|
@ -24,10 +24,10 @@
|
|||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/MC/MCAsmBackend.h"
|
#include "llvm/MC/MCAsmBackend.h"
|
||||||
#include "llvm/MC/MCAssembler.h"
|
#include "llvm/MC/MCAssembler.h"
|
||||||
#include "llvm/MC/MCObjectWriter.h"
|
#include "llvm/MC/MCObjectWriter.h"
|
||||||
|
@ -174,6 +174,7 @@ $LINK $LIBCXX_ARCHIVE_DIR/libc++.a \
|
|||||||
$LLVM_BUILD/lib/libLLVMObject.a \
|
$LLVM_BUILD/lib/libLLVMObject.a \
|
||||||
$LLVM_BUILD/lib/libLLVMBinaryFormat.a \
|
$LLVM_BUILD/lib/libLLVMBinaryFormat.a \
|
||||||
$LLVM_BUILD/lib/libLLVMDebugInfoDWARF.a \
|
$LLVM_BUILD/lib/libLLVMDebugInfoDWARF.a \
|
||||||
|
$LLVM_BUILD/lib/libLLVMDebugInfoDWARFLowLevel.a \
|
||||||
$LLVM_BUILD/lib/libLLVMDebugInfoGSYM.a \
|
$LLVM_BUILD/lib/libLLVMDebugInfoGSYM.a \
|
||||||
$LLVM_BUILD/lib/libLLVMSupport.a \
|
$LLVM_BUILD/lib/libLLVMSupport.a \
|
||||||
$LLVM_BUILD/lib/libLLVMDebugInfoPDB.a \
|
$LLVM_BUILD/lib/libLLVMDebugInfoPDB.a \
|
||||||
|
@ -36,7 +36,8 @@
|
|||||||
#include "lldb/Target/StackID.h"
|
#include "lldb/Target/StackID.h"
|
||||||
#include "lldb/Target/Target.h"
|
#include "lldb/Target/Target.h"
|
||||||
#include "lldb/Target/Thread.h"
|
#include "lldb/Target/Thread.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
|
|
||||||
using namespace lldb;
|
using namespace lldb;
|
||||||
using namespace lldb_private;
|
using namespace lldb_private;
|
||||||
@ -81,7 +82,7 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level,
|
|||||||
llvm::DIDumpOptions DumpOpts;
|
llvm::DIDumpOptions DumpOpts;
|
||||||
DumpOpts.GetNameForDWARFReg = GetRegName;
|
DumpOpts.GetNameForDWARFReg = GetRegName;
|
||||||
llvm::DWARFExpression E(m_data.GetAsLLVM(), m_data.GetAddressByteSize());
|
llvm::DWARFExpression E(m_data.GetAsLLVM(), m_data.GetAddressByteSize());
|
||||||
llvm::DWARFExpressionPrinter::print(&E, s->AsRawOstream(), DumpOpts, nullptr);
|
llvm::printDwarfExpression(&E, s->AsRawOstream(), DumpOpts, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }
|
RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
#include "lldb/Utility/Log.h"
|
#include "lldb/Utility/Log.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/DebugInfo/DIContext.h"
|
#include "llvm/DebugInfo/DIContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
using namespace lldb;
|
using namespace lldb;
|
||||||
@ -89,8 +90,7 @@ static void DumpDWARFExpr(Stream &s, llvm::ArrayRef<uint8_t> expr, Thread *threa
|
|||||||
order_and_width->second);
|
order_and_width->second);
|
||||||
llvm::DWARFExpression E(data, order_and_width->second,
|
llvm::DWARFExpression E(data, order_and_width->second,
|
||||||
llvm::dwarf::DWARF32);
|
llvm::dwarf::DWARF32);
|
||||||
llvm::DWARFExpressionPrinter::print(&E, s.AsRawOstream(),
|
printDwarfExpression(&E, s.AsRawOstream(), llvm::DIDumpOptions(), nullptr);
|
||||||
llvm::DIDumpOptions(), nullptr);
|
|
||||||
} else
|
} else
|
||||||
s.PutCString("dwarf-expr");
|
s.PutCString("dwarf-expr");
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
#include "lldb/Utility/StreamString.h"
|
#include "lldb/Utility/StreamString.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/DebugInfo/DIContext.h"
|
#include "llvm/DebugInfo/DIContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/FormatVariadic.h"
|
#include "llvm/Support/FormatVariadic.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
@ -160,7 +161,7 @@ static std::string ParseAndGenerateDWARF(llvm::StringRef expr) {
|
|||||||
std::string result;
|
std::string result;
|
||||||
llvm::raw_string_ostream os(result);
|
llvm::raw_string_ostream os(result);
|
||||||
llvm::DWARFExpression E(extractor, addr_size, llvm::dwarf::DWARF32);
|
llvm::DWARFExpression E(extractor, addr_size, llvm::dwarf::DWARF32);
|
||||||
llvm::DWARFExpressionPrinter::print(&E, os, llvm::DIDumpOptions(), nullptr);
|
llvm::printDwarfExpression(&E, os, llvm::DIDumpOptions(), nullptr);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
#include "lldb/Utility/StreamBuffer.h"
|
#include "lldb/Utility/StreamBuffer.h"
|
||||||
#include "lldb/Utility/StreamString.h"
|
#include "lldb/Utility/StreamString.h"
|
||||||
#include "llvm/DebugInfo/DIContext.h"
|
#include "llvm/DebugInfo/DIContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
|
|
||||||
using namespace lldb;
|
using namespace lldb;
|
||||||
using namespace lldb_private;
|
using namespace lldb_private;
|
||||||
@ -40,7 +41,7 @@ CheckValidProgramTranslation(llvm::StringRef fpo_program,
|
|||||||
std::string result;
|
std::string result;
|
||||||
llvm::raw_string_ostream os(result);
|
llvm::raw_string_ostream os(result);
|
||||||
llvm::DWARFExpression E(extractor, /*AddressSize=*/4, llvm::dwarf::DWARF32);
|
llvm::DWARFExpression E(extractor, /*AddressSize=*/4, llvm::dwarf::DWARF32);
|
||||||
llvm::DWARFExpressionPrinter::print(&E, os, llvm::DIDumpOptions(), nullptr);
|
llvm::printDwarfExpression(&E, os, llvm::DIDumpOptions(), nullptr);
|
||||||
|
|
||||||
// actual check
|
// actual check
|
||||||
ASSERT_EQ(expected_dwarf_expression, result);
|
ASSERT_EQ(expected_dwarf_expression, result);
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
#include "llvm/ADT/AddressRanges.h"
|
#include "llvm/ADT/AddressRanges.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#ifndef LLVM_DEBUGINFO_DWARF_DWARFCFIPRINTER_H
|
#ifndef LLVM_DEBUGINFO_DWARF_DWARFCFIPRINTER_H
|
||||||
#define LLVM_DEBUGINFO_DWARF_DWARFCFIPRINTER_H
|
#define LLVM_DEBUGINFO_DWARF_DWARFCFIPRINTER_H
|
||||||
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
#define LLVM_DEBUGINFO_DWARF_DWARFDATAEXTRACTOR_H
|
#define LLVM_DEBUGINFO_DWARF_DWARFDATAEXTRACTOR_H
|
||||||
|
|
||||||
#include "llvm/BinaryFormat/Dwarf.h"
|
#include "llvm/BinaryFormat/Dwarf.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDataExtractorSimple.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFObject.h"
|
#include "llvm/DebugInfo/DWARF/DWARFObject.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
|
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/iterator.h"
|
#include "llvm/ADT/iterator.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
#include "llvm/TargetParser/Triple.h"
|
#include "llvm/TargetParser/Triple.h"
|
||||||
|
66
llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h
Normal file
66
llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
//===--- DWARFExpressionPRinter.h - DWARF Expression Printing ---*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_DEBUGINFO_DWARF_DWARFEXPRESSIONPRINTER_H
|
||||||
|
#define LLVM_DEBUGINFO_DWARF_DWARFEXPRESSIONPRINTER_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/ADT/iterator.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
|
#include "llvm/Support/Compiler.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
// This functionality is separated from the main data structure so that nothing
|
||||||
|
// in DWARFExpression.cpp needs build-time dependencies on DWARFUnit or other
|
||||||
|
// higher-level Dwarf structures. This approach creates better layering and
|
||||||
|
// allows DWARFExpression to be used from code which can't have dependencies on
|
||||||
|
// those higher-level structures.
|
||||||
|
|
||||||
|
class DWARFUnit;
|
||||||
|
struct DIDumpOptions;
|
||||||
|
class raw_ostream;
|
||||||
|
|
||||||
|
/// Print a Dwarf expression/
|
||||||
|
/// \param E to be printed
|
||||||
|
/// \param OS to this stream
|
||||||
|
/// \param GetNameForDWARFReg callback to return dwarf register name
|
||||||
|
LLVM_ABI void printDwarfExpression(const DWARFExpression *E, raw_ostream &OS,
|
||||||
|
DIDumpOptions DumpOpts, DWARFUnit *U,
|
||||||
|
bool IsEH = false);
|
||||||
|
|
||||||
|
/// Print the expression in a format intended to be compact and useful to a
|
||||||
|
/// user, but not perfectly unambiguous, or capable of representing every
|
||||||
|
/// valid DWARF expression. Returns true if the expression was sucessfully
|
||||||
|
/// printed.
|
||||||
|
///
|
||||||
|
/// \param E to be printed
|
||||||
|
/// \param OS to this stream
|
||||||
|
/// \param GetNameForDWARFReg callback to return dwarf register name
|
||||||
|
///
|
||||||
|
/// \returns true if the expression was successfully printed
|
||||||
|
LLVM_ABI bool printDwarfExpressionCompact(
|
||||||
|
const DWARFExpression *E, raw_ostream &OS,
|
||||||
|
std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg =
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
/// Pretty print a register opcode and operands.
|
||||||
|
/// \param U within the context of this Dwarf unit, if any.
|
||||||
|
/// \param OS to this stream
|
||||||
|
/// \param DumpOpts with these options
|
||||||
|
/// \param Opcode to print
|
||||||
|
/// \param Operands to the opcode
|
||||||
|
///
|
||||||
|
/// returns true if the Op was successfully printed
|
||||||
|
LLVM_ABI bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
|
||||||
|
DIDumpOptions DumpOpts, uint8_t Opcode,
|
||||||
|
ArrayRef<uint64_t> Operands);
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_DEBUGINFO_DWARF_DWARFEXPRESSIONPRINTER_H
|
@ -14,8 +14,8 @@
|
|||||||
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
|
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
|
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/iterator.h"
|
#include "llvm/ADT/iterator.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
#include "llvm/TargetParser/Triple.h"
|
#include "llvm/TargetParser/Triple.h"
|
||||||
@ -78,8 +78,150 @@ public:
|
|||||||
/// starting at *Offset and ending at EndOffset. *Offset is updated
|
/// starting at *Offset and ending at EndOffset. *Offset is updated
|
||||||
/// to EndOffset upon successful parsing, or indicates the offset
|
/// to EndOffset upon successful parsing, or indicates the offset
|
||||||
/// where a problem occurred in case an error is returned.
|
/// where a problem occurred in case an error is returned.
|
||||||
LLVM_ABI Error parse(DWARFDataExtractor Data, uint64_t *Offset,
|
template <typename T>
|
||||||
uint64_t EndOffset);
|
LLVM_ABI Error parse(DWARFDataExtractorBase<T> &Data, uint64_t *Offset,
|
||||||
|
uint64_t EndOffset) {
|
||||||
|
// See DWARF standard v3, section 7.23
|
||||||
|
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
|
||||||
|
const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
|
||||||
|
|
||||||
|
DataExtractor::Cursor C(*Offset);
|
||||||
|
while (C && C.tell() < EndOffset) {
|
||||||
|
uint8_t Opcode = Data.getRelocatedValue(C, 1);
|
||||||
|
if (!C)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Some instructions have a primary opcode encoded in the top bits.
|
||||||
|
if (uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) {
|
||||||
|
// If it's a primary opcode, the first operand is encoded in the
|
||||||
|
// bottom bits of the opcode itself.
|
||||||
|
uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
|
||||||
|
switch (Primary) {
|
||||||
|
case DW_CFA_advance_loc:
|
||||||
|
case DW_CFA_restore:
|
||||||
|
addInstruction(Primary, Op1);
|
||||||
|
break;
|
||||||
|
case DW_CFA_offset:
|
||||||
|
addInstruction(Primary, Op1, Data.getULEB128(C));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
llvm_unreachable("invalid primary CFI opcode");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extended opcode - its value is Opcode itself.
|
||||||
|
switch (Opcode) {
|
||||||
|
default:
|
||||||
|
return createStringError(errc::illegal_byte_sequence,
|
||||||
|
"invalid extended CFI opcode 0x%" PRIx8,
|
||||||
|
Opcode);
|
||||||
|
case DW_CFA_nop:
|
||||||
|
case DW_CFA_remember_state:
|
||||||
|
case DW_CFA_restore_state:
|
||||||
|
case DW_CFA_GNU_window_save:
|
||||||
|
case DW_CFA_AARCH64_negate_ra_state_with_pc:
|
||||||
|
// No operands
|
||||||
|
addInstruction(Opcode);
|
||||||
|
break;
|
||||||
|
case DW_CFA_set_loc:
|
||||||
|
// Operands: Address
|
||||||
|
addInstruction(Opcode, Data.getRelocatedAddress(C));
|
||||||
|
break;
|
||||||
|
case DW_CFA_advance_loc1:
|
||||||
|
// Operands: 1-byte delta
|
||||||
|
addInstruction(Opcode, Data.getRelocatedValue(C, 1));
|
||||||
|
break;
|
||||||
|
case DW_CFA_advance_loc2:
|
||||||
|
// Operands: 2-byte delta
|
||||||
|
addInstruction(Opcode, Data.getRelocatedValue(C, 2));
|
||||||
|
break;
|
||||||
|
case DW_CFA_advance_loc4:
|
||||||
|
// Operands: 4-byte delta
|
||||||
|
addInstruction(Opcode, Data.getRelocatedValue(C, 4));
|
||||||
|
break;
|
||||||
|
case DW_CFA_restore_extended:
|
||||||
|
case DW_CFA_undefined:
|
||||||
|
case DW_CFA_same_value:
|
||||||
|
case DW_CFA_def_cfa_register:
|
||||||
|
case DW_CFA_def_cfa_offset:
|
||||||
|
case DW_CFA_GNU_args_size:
|
||||||
|
// Operands: ULEB128
|
||||||
|
addInstruction(Opcode, Data.getULEB128(C));
|
||||||
|
break;
|
||||||
|
case DW_CFA_def_cfa_offset_sf:
|
||||||
|
// Operands: SLEB128
|
||||||
|
addInstruction(Opcode, Data.getSLEB128(C));
|
||||||
|
break;
|
||||||
|
case DW_CFA_LLVM_def_aspace_cfa:
|
||||||
|
case DW_CFA_LLVM_def_aspace_cfa_sf: {
|
||||||
|
auto RegNum = Data.getULEB128(C);
|
||||||
|
auto CfaOffset = Opcode == DW_CFA_LLVM_def_aspace_cfa
|
||||||
|
? Data.getULEB128(C)
|
||||||
|
: Data.getSLEB128(C);
|
||||||
|
auto AddressSpace = Data.getULEB128(C);
|
||||||
|
addInstruction(Opcode, RegNum, CfaOffset, AddressSpace);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DW_CFA_offset_extended:
|
||||||
|
case DW_CFA_register:
|
||||||
|
case DW_CFA_def_cfa:
|
||||||
|
case DW_CFA_val_offset: {
|
||||||
|
// Operands: ULEB128, ULEB128
|
||||||
|
// Note: We can not embed getULEB128 directly into function
|
||||||
|
// argument list. getULEB128 changes Offset and order of evaluation
|
||||||
|
// for arguments is unspecified.
|
||||||
|
uint64_t op1 = Data.getULEB128(C);
|
||||||
|
uint64_t op2 = Data.getULEB128(C);
|
||||||
|
addInstruction(Opcode, op1, op2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DW_CFA_offset_extended_sf:
|
||||||
|
case DW_CFA_def_cfa_sf:
|
||||||
|
case DW_CFA_val_offset_sf: {
|
||||||
|
// Operands: ULEB128, SLEB128
|
||||||
|
// Note: see comment for the previous case
|
||||||
|
uint64_t op1 = Data.getULEB128(C);
|
||||||
|
uint64_t op2 = (uint64_t)Data.getSLEB128(C);
|
||||||
|
addInstruction(Opcode, op1, op2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DW_CFA_def_cfa_expression: {
|
||||||
|
uint64_t ExprLength = Data.getULEB128(C);
|
||||||
|
addInstruction(Opcode, 0);
|
||||||
|
StringRef Expression = Data.getBytes(C, ExprLength);
|
||||||
|
|
||||||
|
DataExtractor Extractor(Expression, Data.isLittleEndian(),
|
||||||
|
Data.getAddressSize());
|
||||||
|
// Note. We do not pass the DWARF format to DWARFExpression, because
|
||||||
|
// DW_OP_call_ref, the only operation which depends on the format, is
|
||||||
|
// prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
|
||||||
|
Instructions.back().Expression =
|
||||||
|
DWARFExpression(Extractor, Data.getAddressSize());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DW_CFA_expression:
|
||||||
|
case DW_CFA_val_expression: {
|
||||||
|
uint64_t RegNum = Data.getULEB128(C);
|
||||||
|
addInstruction(Opcode, RegNum, 0);
|
||||||
|
|
||||||
|
uint64_t BlockLength = Data.getULEB128(C);
|
||||||
|
StringRef Expression = Data.getBytes(C, BlockLength);
|
||||||
|
DataExtractor Extractor(Expression, Data.isLittleEndian(),
|
||||||
|
Data.getAddressSize());
|
||||||
|
// Note. We do not pass the DWARF format to DWARFExpression, because
|
||||||
|
// DW_OP_call_ref, the only operation which depends on the format, is
|
||||||
|
// prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
|
||||||
|
Instructions.back().Expression =
|
||||||
|
DWARFExpression(Extractor, Data.getAddressSize());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*Offset = C.tell();
|
||||||
|
return C.takeError();
|
||||||
|
}
|
||||||
|
|
||||||
void addInstruction(const Instruction &I) { Instructions.push_back(I); }
|
void addInstruction(const Instruction &I) { Instructions.push_back(I); }
|
||||||
|
|
@ -77,7 +77,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
friend class DWARFExpression::iterator;
|
friend class DWARFExpression::iterator;
|
||||||
friend class DWARFExpressionPrinter;
|
|
||||||
friend class DWARFVerifier;
|
friend class DWARFVerifier;
|
||||||
|
|
||||||
uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
|
uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
|
||||||
@ -156,7 +155,6 @@ public:
|
|||||||
|
|
||||||
StringRef getData() const { return Data.getData(); }
|
StringRef getData() const { return Data.getData(); }
|
||||||
|
|
||||||
friend class DWARFExpressionPrinter;
|
|
||||||
friend class DWARFVerifier;
|
friend class DWARFVerifier;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -170,65 +168,6 @@ inline bool operator==(const DWARFExpression::iterator &LHS,
|
|||||||
return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
|
return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This functionality is separated from the main data structure so that nothing
|
|
||||||
// in DWARFExpression.cpp needs build-time dependencies on DWARFUnit or other
|
|
||||||
// higher-level Dwarf structures. This approach creates better layering and
|
|
||||||
// allows DWARFExpression to be used from code which can't have dependencies on
|
|
||||||
// those higher-level structures.
|
|
||||||
|
|
||||||
class DWARFUnit;
|
|
||||||
struct DIDumpOptions;
|
|
||||||
class raw_ostream;
|
|
||||||
|
|
||||||
class DWARFExpressionPrinter {
|
|
||||||
public:
|
|
||||||
/// Print a Dwarf expression/
|
|
||||||
/// \param E to be printed
|
|
||||||
/// \param OS to this stream
|
|
||||||
/// \param GetNameForDWARFReg callback to return dwarf register name
|
|
||||||
LLVM_ABI static void print(const DWARFExpression *E, raw_ostream &OS,
|
|
||||||
DIDumpOptions DumpOpts, DWARFUnit *U,
|
|
||||||
bool IsEH = false);
|
|
||||||
|
|
||||||
/// Print the expression in a format intended to be compact and useful to a
|
|
||||||
/// user, but not perfectly unambiguous, or capable of representing every
|
|
||||||
/// valid DWARF expression. Returns true if the expression was sucessfully
|
|
||||||
/// printed.
|
|
||||||
///
|
|
||||||
/// \param E to be printed
|
|
||||||
/// \param OS to this stream
|
|
||||||
/// \param GetNameForDWARFReg callback to return dwarf register name
|
|
||||||
///
|
|
||||||
/// \returns true if the expression was successfully printed
|
|
||||||
LLVM_ABI static bool printCompact(
|
|
||||||
const DWARFExpression *E, raw_ostream &OS,
|
|
||||||
std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg =
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
/// Pretty print a register opcode and operands.
|
|
||||||
/// \param U within the context of this Dwarf unit, if any.
|
|
||||||
/// \param OS to this stream
|
|
||||||
/// \param DumpOpts with these options
|
|
||||||
/// \param Opcode to print
|
|
||||||
/// \param Operands to the opcode
|
|
||||||
///
|
|
||||||
/// returns true if the Op was successfully printed
|
|
||||||
LLVM_ABI static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
|
|
||||||
DIDumpOptions DumpOpts,
|
|
||||||
uint8_t Opcode,
|
|
||||||
ArrayRef<uint64_t> Operands);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
|
|
||||||
DIDumpOptions DumpOpts, const DWARFExpression *Expr,
|
|
||||||
DWARFUnit *U);
|
|
||||||
|
|
||||||
static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
|
|
||||||
DIDumpOptions DumpOpts,
|
|
||||||
ArrayRef<uint64_t> Operands,
|
|
||||||
unsigned Operand);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
#endif // LLVM_DEBUGINFO_DWARF_DWARFEXPRESSION_H
|
#endif // LLVM_DEBUGINFO_DWARF_DWARFEXPRESSION_H
|
@ -38,6 +38,7 @@ add_llvm_component_library(LLVMAsmPrinter
|
|||||||
Core
|
Core
|
||||||
DebugInfoCodeView
|
DebugInfoCodeView
|
||||||
DebugInfoDWARF
|
DebugInfoDWARF
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
MC
|
MC
|
||||||
MCParser
|
MCParser
|
||||||
Remarks
|
Remarks
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
||||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/DebugInfoMetadata.h"
|
#include "llvm/IR/DebugInfoMetadata.h"
|
||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
|
@ -19,6 +19,7 @@ add_llvm_component_library(LLVMDWARFLinkerClassic
|
|||||||
CodeGen
|
CodeGen
|
||||||
CodeGenTypes
|
CodeGenTypes
|
||||||
DebugInfoDWARF
|
DebugInfoDWARF
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
DWARFLinker
|
DWARFLinker
|
||||||
MC
|
MC
|
||||||
Object
|
Object
|
||||||
|
@ -23,10 +23,10 @@
|
|||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/MC/MCDwarf.h"
|
#include "llvm/MC/MCDwarf.h"
|
||||||
#include "llvm/Support/DataExtractor.h"
|
#include "llvm/Support/DataExtractor.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/DWARFLinker/Classic/DWARFLinkerDeclContext.h"
|
#include "llvm/DWARFLinker/Classic/DWARFLinkerDeclContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/FormatVariadic.h"
|
#include "llvm/Support/FormatVariadic.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -25,6 +25,7 @@ add_llvm_component_library(LLVMDWARFLinkerParallel
|
|||||||
BinaryFormat
|
BinaryFormat
|
||||||
CodeGen
|
CodeGen
|
||||||
DebugInfoDWARF
|
DebugInfoDWARF
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
DWARFLinker
|
DWARFLinker
|
||||||
MC
|
MC
|
||||||
Object
|
Object
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
|
add_subdirectory(LowLevel)
|
||||||
|
|
||||||
add_llvm_component_library(LLVMDebugInfoDWARF
|
add_llvm_component_library(LLVMDebugInfoDWARF
|
||||||
DWARFAbbreviationDeclaration.cpp
|
DWARFAbbreviationDeclaration.cpp
|
||||||
DWARFAddressRange.cpp
|
DWARFAddressRange.cpp
|
||||||
DWARFAcceleratorTable.cpp
|
DWARFAcceleratorTable.cpp
|
||||||
DWARFCFIPrinter.cpp
|
DWARFCFIPrinter.cpp
|
||||||
DWARFCFIProgram.cpp
|
|
||||||
DWARFCompileUnit.cpp
|
DWARFCompileUnit.cpp
|
||||||
DWARFContext.cpp
|
DWARFContext.cpp
|
||||||
DWARFDebugAbbrev.cpp
|
DWARFDebugAbbrev.cpp
|
||||||
@ -19,7 +20,7 @@ add_llvm_component_library(LLVMDebugInfoDWARF
|
|||||||
DWARFDebugRangeList.cpp
|
DWARFDebugRangeList.cpp
|
||||||
DWARFDebugRnglists.cpp
|
DWARFDebugRnglists.cpp
|
||||||
DWARFDie.cpp
|
DWARFDie.cpp
|
||||||
DWARFExpression.cpp
|
DWARFExpressionPrinter.cpp
|
||||||
DWARFFormValue.cpp
|
DWARFFormValue.cpp
|
||||||
DWARFGdbIndex.cpp
|
DWARFGdbIndex.cpp
|
||||||
DWARFListTable.cpp
|
DWARFListTable.cpp
|
||||||
@ -35,6 +36,7 @@ add_llvm_component_library(LLVMDebugInfoDWARF
|
|||||||
|
|
||||||
LINK_COMPONENTS
|
LINK_COMPONENTS
|
||||||
BinaryFormat
|
BinaryFormat
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
Object
|
Object
|
||||||
Support
|
Support
|
||||||
TargetParser
|
TargetParser
|
||||||
|
@ -8,8 +8,9 @@
|
|||||||
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFCFIPrinter.h"
|
#include "llvm/DebugInfo/DWARF/DWARFCFIPrinter.h"
|
||||||
#include "llvm/DebugInfo/DIContext.h"
|
#include "llvm/DebugInfo/DIContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/DataExtractor.h"
|
#include "llvm/Support/DataExtractor.h"
|
||||||
#include "llvm/Support/Errc.h"
|
#include "llvm/Support/Errc.h"
|
||||||
@ -100,8 +101,7 @@ static void printOperand(raw_ostream &OS, const DIDumpOptions &DumpOpts,
|
|||||||
case CFIProgram::OT_Expression:
|
case CFIProgram::OT_Expression:
|
||||||
assert(Instr.Expression && "missing DWARFExpression object");
|
assert(Instr.Expression && "missing DWARFExpression object");
|
||||||
OS << " ";
|
OS << " ";
|
||||||
DWARFExpressionPrinter::print(&Instr.Expression.value(), OS, DumpOpts,
|
printDwarfExpression(&Instr.Expression.value(), OS, DumpOpts, nullptr);
|
||||||
nullptr);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,10 @@
|
|||||||
#include "llvm/BinaryFormat/Dwarf.h"
|
#include "llvm/BinaryFormat/Dwarf.h"
|
||||||
#include "llvm/DebugInfo/DIContext.h"
|
#include "llvm/DebugInfo/DIContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFCFIPrinter.h"
|
#include "llvm/DebugInfo/DWARF/DWARFCFIPrinter.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/DataExtractor.h"
|
#include "llvm/Support/DataExtractor.h"
|
||||||
#include "llvm/Support/Errc.h"
|
#include "llvm/Support/Errc.h"
|
||||||
@ -114,7 +115,7 @@ void UnwindLocation::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
|
|||||||
break;
|
break;
|
||||||
case DWARFExpr: {
|
case DWARFExpr: {
|
||||||
if (Expr)
|
if (Expr)
|
||||||
DWARFExpressionPrinter::print(&(*Expr), OS, DumpOpts, nullptr);
|
printDwarfExpression(&Expr.value(), OS, DumpOpts, nullptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Constant:
|
case Constant:
|
||||||
|
@ -11,10 +11,11 @@
|
|||||||
#include "llvm/BinaryFormat/Dwarf.h"
|
#include "llvm/BinaryFormat/Dwarf.h"
|
||||||
#include "llvm/DebugInfo/DIContext.h"
|
#include "llvm/DebugInfo/DIContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
|
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/Format.h"
|
#include "llvm/Support/Format.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -117,7 +118,7 @@ static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
|
|||||||
if (U)
|
if (U)
|
||||||
Format = U->getFormat();
|
Format = U->getFormat();
|
||||||
DWARFExpression E(Extractor, AddressSize, Format);
|
DWARFExpression E(Extractor, AddressSize, Format);
|
||||||
DWARFExpressionPrinter::print(&E, OS, DumpOpts, U);
|
printDwarfExpression(&E, OS, DumpOpts, U);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DWARFLocationTable::dumpLocationList(
|
bool DWARFLocationTable::dumpLocationList(
|
||||||
|
@ -15,11 +15,12 @@
|
|||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
|
#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Object/ObjectFile.h"
|
#include "llvm/Object/ObjectFile.h"
|
||||||
#include "llvm/Support/DataExtractor.h"
|
#include "llvm/Support/DataExtractor.h"
|
||||||
#include "llvm/Support/Format.h"
|
#include "llvm/Support/Format.h"
|
||||||
@ -99,7 +100,7 @@ static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue,
|
|||||||
DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
|
DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
|
||||||
Ctx.isLittleEndian(), 0);
|
Ctx.isLittleEndian(), 0);
|
||||||
DWARFExpression DE(Data, U->getAddressByteSize(), U->getFormParams().Format);
|
DWARFExpression DE(Data, U->getAddressByteSize(), U->getFormParams().Format);
|
||||||
DWARFExpressionPrinter::print(&DE, OS, DumpOpts, U);
|
printDwarfExpression(&DE, OS, DumpOpts, U);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
|
static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
|
||||||
|
@ -1,538 +0,0 @@
|
|||||||
//===-- DWARFExpression.cpp -----------------------------------------------===//
|
|
||||||
//
|
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
||||||
#include "llvm/ADT/SmallString.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
|
||||||
#include "llvm/Support/Format.h"
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
using namespace llvm;
|
|
||||||
using namespace dwarf;
|
|
||||||
|
|
||||||
namespace llvm {
|
|
||||||
|
|
||||||
typedef DWARFExpression::Operation Op;
|
|
||||||
typedef Op::Description Desc;
|
|
||||||
|
|
||||||
static std::vector<Desc> getOpDescriptions() {
|
|
||||||
std::vector<Desc> Descriptions;
|
|
||||||
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_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);
|
|
||||||
Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2);
|
|
||||||
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::Dwarf4, Op::SizeLEB, Op::SizeBlock);
|
|
||||||
Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf4);
|
|
||||||
Descriptions[DW_OP_implicit_pointer] =
|
|
||||||
Desc(Op::Dwarf5, Op::SizeRefAddr, Op::SignedSizeLEB);
|
|
||||||
Descriptions[DW_OP_addrx] = Desc(Op::Dwarf5, Op::SizeLEB);
|
|
||||||
Descriptions[DW_OP_constx] = Desc(Op::Dwarf5, Op::SizeLEB);
|
|
||||||
Descriptions[DW_OP_entry_value] = Desc(Op::Dwarf5, Op::SizeLEB);
|
|
||||||
Descriptions[DW_OP_convert] = Desc(Op::Dwarf5, Op::BaseTypeRef);
|
|
||||||
Descriptions[DW_OP_regval_type] =
|
|
||||||
Desc(Op::Dwarf5, Op::SizeLEB, Op::BaseTypeRef);
|
|
||||||
Descriptions[DW_OP_WASM_location] =
|
|
||||||
Desc(Op::Dwarf4, Op::SizeLEB, Op::WasmLocationArg);
|
|
||||||
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);
|
|
||||||
Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB);
|
|
||||||
Descriptions[DW_OP_GNU_implicit_pointer] =
|
|
||||||
Desc(Op::Dwarf4, Op::SizeRefAddr, Op::SignedSizeLEB);
|
|
||||||
// This Description acts as a marker that getSubOpDesc must be called
|
|
||||||
// to fetch the final Description for the operation. Each such final
|
|
||||||
// Description must share the same first SizeSubOpLEB operand.
|
|
||||||
Descriptions[DW_OP_LLVM_user] = Desc(Op::Dwarf5, Op::SizeSubOpLEB);
|
|
||||||
return Descriptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Desc getDescImpl(ArrayRef<Desc> Descriptions, unsigned Opcode) {
|
|
||||||
// Handle possible corrupted or unsupported operation.
|
|
||||||
if (Opcode >= Descriptions.size())
|
|
||||||
return {};
|
|
||||||
return Descriptions[Opcode];
|
|
||||||
}
|
|
||||||
|
|
||||||
static Desc getOpDesc(unsigned Opcode) {
|
|
||||||
static std::vector<Desc> Descriptions = getOpDescriptions();
|
|
||||||
return getDescImpl(Descriptions, Opcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<Desc> getSubOpDescriptions() {
|
|
||||||
static constexpr unsigned LlvmUserDescriptionsSize = 1
|
|
||||||
#define HANDLE_DW_OP_LLVM_USEROP(ID, NAME) +1
|
|
||||||
#include "llvm/BinaryFormat/Dwarf.def"
|
|
||||||
;
|
|
||||||
std::vector<Desc> Descriptions;
|
|
||||||
Descriptions.resize(LlvmUserDescriptionsSize);
|
|
||||||
Descriptions[DW_OP_LLVM_nop] = Desc(Op::Dwarf5, Op::SizeSubOpLEB);
|
|
||||||
return Descriptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Desc getSubOpDesc(unsigned Opcode, unsigned SubOpcode) {
|
|
||||||
assert(Opcode == DW_OP_LLVM_user);
|
|
||||||
static std::vector<Desc> Descriptions = getSubOpDescriptions();
|
|
||||||
return getDescImpl(Descriptions, SubOpcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DWARFExpression::Operation::extract(DataExtractor Data,
|
|
||||||
uint8_t AddressSize, uint64_t Offset,
|
|
||||||
std::optional<DwarfFormat> Format) {
|
|
||||||
EndOffset = Offset;
|
|
||||||
Opcode = Data.getU8(&Offset);
|
|
||||||
|
|
||||||
Desc = getOpDesc(Opcode);
|
|
||||||
if (Desc.Version == Operation::DwarfNA)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Operands.resize(Desc.Op.size());
|
|
||||||
OperandEndOffsets.resize(Desc.Op.size());
|
|
||||||
for (unsigned Operand = 0; Operand < Desc.Op.size(); ++Operand) {
|
|
||||||
unsigned Size = Desc.Op[Operand];
|
|
||||||
unsigned Signed = Size & Operation::SignBit;
|
|
||||||
|
|
||||||
switch (Size & ~Operation::SignBit) {
|
|
||||||
case Operation::SizeSubOpLEB:
|
|
||||||
assert(Operand == 0 && "SubOp operand must be the first operand");
|
|
||||||
Operands[Operand] = Data.getULEB128(&Offset);
|
|
||||||
Desc = getSubOpDesc(Opcode, Operands[Operand]);
|
|
||||||
if (Desc.Version == Operation::DwarfNA)
|
|
||||||
return false;
|
|
||||||
assert(Desc.Op[Operand] == Operation::SizeSubOpLEB &&
|
|
||||||
"SizeSubOpLEB Description must begin with SizeSubOpLEB operand");
|
|
||||||
break;
|
|
||||||
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:
|
|
||||||
Operands[Operand] = Data.getUnsigned(&Offset, AddressSize);
|
|
||||||
break;
|
|
||||||
case Operation::SizeRefAddr:
|
|
||||||
if (!Format)
|
|
||||||
return false;
|
|
||||||
Operands[Operand] =
|
|
||||||
Data.getUnsigned(&Offset, dwarf::getDwarfOffsetByteSize(*Format));
|
|
||||||
break;
|
|
||||||
case Operation::SizeLEB:
|
|
||||||
if (Signed)
|
|
||||||
Operands[Operand] = Data.getSLEB128(&Offset);
|
|
||||||
else
|
|
||||||
Operands[Operand] = Data.getULEB128(&Offset);
|
|
||||||
break;
|
|
||||||
case Operation::BaseTypeRef:
|
|
||||||
Operands[Operand] = Data.getULEB128(&Offset);
|
|
||||||
break;
|
|
||||||
case Operation::WasmLocationArg:
|
|
||||||
assert(Operand == 1);
|
|
||||||
switch (Operands[0]) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
case 4:
|
|
||||||
Operands[Operand] = Data.getULEB128(&Offset);
|
|
||||||
break;
|
|
||||||
case 3: // global as uint32
|
|
||||||
Operands[Operand] = Data.getU32(&Offset);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false; // Unknown Wasm location
|
|
||||||
}
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
OperandEndOffsets[Operand] = Offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
EndOffset = Offset;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<unsigned> DWARFExpression::Operation::getSubCode() const {
|
|
||||||
if (!Desc.Op.size() || Desc.Op[0] != Operation::SizeSubOpLEB)
|
|
||||||
return std::nullopt;
|
|
||||||
return Operands[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DWARFExpression::operator==(const DWARFExpression &RHS) const {
|
|
||||||
if (AddressSize != RHS.AddressSize || Format != RHS.Format)
|
|
||||||
return false;
|
|
||||||
return Data.getData() == RHS.Data.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DWARFExpressionPrinter::prettyPrintBaseTypeRef(DWARFUnit *U,
|
|
||||||
raw_ostream &OS,
|
|
||||||
DIDumpOptions DumpOpts,
|
|
||||||
ArrayRef<uint64_t> Operands,
|
|
||||||
unsigned Operand) {
|
|
||||||
assert(Operand < Operands.size() && "operand out of bounds");
|
|
||||||
if (!U) {
|
|
||||||
OS << format(" <base_type ref: 0x%" PRIx64 ">", Operands[Operand]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
|
|
||||||
if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
|
|
||||||
OS << " (";
|
|
||||||
if (DumpOpts.Verbose)
|
|
||||||
OS << format("0x%08" PRIx64 " -> ", Operands[Operand]);
|
|
||||||
OS << format("0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
|
|
||||||
if (auto Name = dwarf::toString(Die.find(dwarf::DW_AT_name)))
|
|
||||||
OS << " \"" << *Name << "\"";
|
|
||||||
} else {
|
|
||||||
OS << format(" <invalid base_type ref: 0x%" PRIx64 ">", Operands[Operand]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DWARFExpressionPrinter::prettyPrintRegisterOp(
|
|
||||||
DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, uint8_t Opcode,
|
|
||||||
ArrayRef<uint64_t> Operands) {
|
|
||||||
if (!DumpOpts.GetNameForDWARFReg)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint64_t DwarfRegNum;
|
|
||||||
unsigned OpNum = 0;
|
|
||||||
|
|
||||||
if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
|
|
||||||
Opcode == DW_OP_regval_type)
|
|
||||||
DwarfRegNum = Operands[OpNum++];
|
|
||||||
else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
|
|
||||||
DwarfRegNum = Opcode - DW_OP_breg0;
|
|
||||||
else
|
|
||||||
DwarfRegNum = Opcode - DW_OP_reg0;
|
|
||||||
|
|
||||||
auto RegName = DumpOpts.GetNameForDWARFReg(DwarfRegNum, DumpOpts.IsEH);
|
|
||||||
if (!RegName.empty()) {
|
|
||||||
if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
|
|
||||||
Opcode == DW_OP_bregx)
|
|
||||||
OS << ' ' << RegName << format("%+" PRId64, Operands[OpNum]);
|
|
||||||
else
|
|
||||||
OS << ' ' << RegName.data();
|
|
||||||
|
|
||||||
if (Opcode == DW_OP_regval_type)
|
|
||||||
prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DWARFExpressionPrinter::printOp(const DWARFExpression::Operation *Op,
|
|
||||||
raw_ostream &OS, DIDumpOptions DumpOpts,
|
|
||||||
const DWARFExpression *Expr,
|
|
||||||
DWARFUnit *U) {
|
|
||||||
if (Op->Error) {
|
|
||||||
OS << "<decoding error>";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRef Name = OperationEncodingString(Op->Opcode);
|
|
||||||
assert(!Name.empty() && "DW_OP has no name!");
|
|
||||||
OS << Name;
|
|
||||||
|
|
||||||
if ((Op->Opcode >= DW_OP_breg0 && Op->Opcode <= DW_OP_breg31) ||
|
|
||||||
(Op->Opcode >= DW_OP_reg0 && Op->Opcode <= DW_OP_reg31) ||
|
|
||||||
Op->Opcode == DW_OP_bregx || Op->Opcode == DW_OP_regx ||
|
|
||||||
Op->Opcode == DW_OP_regval_type)
|
|
||||||
if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->Opcode, Op->Operands))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (unsigned Operand = 0; Operand < Op->Desc.Op.size(); ++Operand) {
|
|
||||||
unsigned Size = Op->Desc.Op[Operand];
|
|
||||||
unsigned Signed = Size & DWARFExpression::Operation::SignBit;
|
|
||||||
|
|
||||||
if (Size == DWARFExpression::Operation::SizeSubOpLEB) {
|
|
||||||
StringRef SubName =
|
|
||||||
SubOperationEncodingString(Op->Opcode, Op->Operands[Operand]);
|
|
||||||
assert(!SubName.empty() && "DW_OP SubOp has no name!");
|
|
||||||
OS << " " << SubName;
|
|
||||||
} else if (Size == DWARFExpression::Operation::BaseTypeRef && U) {
|
|
||||||
// For DW_OP_convert the operand may be 0 to indicate that conversion to
|
|
||||||
// the generic type should be done. The same holds for DW_OP_reinterpret,
|
|
||||||
// which is currently not supported.
|
|
||||||
if (Op->Opcode == DW_OP_convert && Op->Operands[Operand] == 0)
|
|
||||||
OS << " 0x0";
|
|
||||||
else
|
|
||||||
prettyPrintBaseTypeRef(U, OS, DumpOpts, Op->Operands, Operand);
|
|
||||||
} else if (Size == DWARFExpression::Operation::WasmLocationArg) {
|
|
||||||
assert(Operand == 1);
|
|
||||||
switch (Op->Operands[0]) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
case 3: // global as uint32
|
|
||||||
case 4:
|
|
||||||
OS << format(" 0x%" PRIx64, Op->Operands[Operand]);
|
|
||||||
break;
|
|
||||||
default: assert(false);
|
|
||||||
}
|
|
||||||
} else if (Size == DWARFExpression::Operation::SizeBlock) {
|
|
||||||
uint64_t Offset = Op->Operands[Operand];
|
|
||||||
for (unsigned i = 0; i < Op->Operands[Operand - 1]; ++i)
|
|
||||||
OS << format(" 0x%02x", Expr->Data.getU8(&Offset));
|
|
||||||
} else {
|
|
||||||
if (Signed)
|
|
||||||
OS << format(" %+" PRId64, (int64_t)Op->Operands[Operand]);
|
|
||||||
else if (Op->Opcode != DW_OP_entry_value &&
|
|
||||||
Op->Opcode != DW_OP_GNU_entry_value)
|
|
||||||
OS << format(" 0x%" PRIx64, Op->Operands[Operand]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DWARFExpressionPrinter::print(const DWARFExpression *E, raw_ostream &OS,
|
|
||||||
DIDumpOptions DumpOpts, DWARFUnit *U,
|
|
||||||
bool IsEH) {
|
|
||||||
uint32_t EntryValExprSize = 0;
|
|
||||||
uint64_t EntryValStartOffset = 0;
|
|
||||||
if (E->Data.getData().empty())
|
|
||||||
OS << "<empty>";
|
|
||||||
|
|
||||||
for (auto &Op : *E) {
|
|
||||||
DumpOpts.IsEH = IsEH;
|
|
||||||
if (!printOp(&Op, OS, DumpOpts, E, U)) {
|
|
||||||
uint64_t FailOffset = Op.getEndOffset();
|
|
||||||
while (FailOffset < E->Data.getData().size())
|
|
||||||
OS << format(" %02x", E->Data.getU8(&FailOffset));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Op.getCode() == DW_OP_entry_value ||
|
|
||||||
Op.getCode() == DW_OP_GNU_entry_value) {
|
|
||||||
OS << "(";
|
|
||||||
EntryValExprSize = Op.getRawOperand(0);
|
|
||||||
EntryValStartOffset = Op.getEndOffset();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EntryValExprSize) {
|
|
||||||
EntryValExprSize -= Op.getEndOffset() - EntryValStartOffset;
|
|
||||||
if (EntryValExprSize == 0)
|
|
||||||
OS << ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Op.getEndOffset() < E->Data.getData().size())
|
|
||||||
OS << ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A user-facing string representation of a DWARF expression. This might be an
|
|
||||||
/// Address expression, in which case it will be implicitly dereferenced, or a
|
|
||||||
/// Value expression.
|
|
||||||
struct PrintedExpr {
|
|
||||||
enum ExprKind {
|
|
||||||
Address,
|
|
||||||
Value,
|
|
||||||
};
|
|
||||||
ExprKind Kind;
|
|
||||||
SmallString<16> String;
|
|
||||||
|
|
||||||
PrintedExpr(ExprKind K = Address) : Kind(K) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool printCompactDWARFExpr(
|
|
||||||
raw_ostream &OS, DWARFExpression::iterator I,
|
|
||||||
const DWARFExpression::iterator E,
|
|
||||||
std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg =
|
|
||||||
nullptr) {
|
|
||||||
SmallVector<PrintedExpr, 4> Stack;
|
|
||||||
|
|
||||||
while (I != E) {
|
|
||||||
const DWARFExpression::Operation &Op = *I;
|
|
||||||
uint8_t Opcode = Op.getCode();
|
|
||||||
switch (Opcode) {
|
|
||||||
case dwarf::DW_OP_regx: {
|
|
||||||
// DW_OP_regx: A register, with the register num given as an operand.
|
|
||||||
// Printed as the plain register name.
|
|
||||||
uint64_t DwarfRegNum = Op.getRawOperand(0);
|
|
||||||
auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
|
|
||||||
if (RegName.empty())
|
|
||||||
return false;
|
|
||||||
raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
|
|
||||||
S << RegName;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case dwarf::DW_OP_bregx: {
|
|
||||||
int DwarfRegNum = Op.getRawOperand(0);
|
|
||||||
int64_t Offset = Op.getRawOperand(1);
|
|
||||||
auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
|
|
||||||
if (RegName.empty())
|
|
||||||
return false;
|
|
||||||
raw_svector_ostream S(Stack.emplace_back().String);
|
|
||||||
S << RegName;
|
|
||||||
if (Offset)
|
|
||||||
S << format("%+" PRId64, Offset);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case dwarf::DW_OP_entry_value:
|
|
||||||
case dwarf::DW_OP_GNU_entry_value: {
|
|
||||||
// DW_OP_entry_value contains a sub-expression which must be rendered
|
|
||||||
// separately.
|
|
||||||
uint64_t SubExprLength = Op.getRawOperand(0);
|
|
||||||
DWARFExpression::iterator SubExprEnd = I.skipBytes(SubExprLength);
|
|
||||||
++I;
|
|
||||||
raw_svector_ostream S(Stack.emplace_back().String);
|
|
||||||
S << "entry(";
|
|
||||||
printCompactDWARFExpr(S, I, SubExprEnd, GetNameForDWARFReg);
|
|
||||||
S << ")";
|
|
||||||
I = SubExprEnd;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
case dwarf::DW_OP_stack_value: {
|
|
||||||
// The top stack entry should be treated as the actual value of tne
|
|
||||||
// variable, rather than the address of the variable in memory.
|
|
||||||
assert(!Stack.empty());
|
|
||||||
Stack.back().Kind = PrintedExpr::Value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case dwarf::DW_OP_nop: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case dwarf::DW_OP_LLVM_user: {
|
|
||||||
assert(Op.getSubCode() == dwarf::DW_OP_LLVM_nop);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) {
|
|
||||||
// DW_OP_reg<N>: A register, with the register num implied by the
|
|
||||||
// opcode. Printed as the plain register name.
|
|
||||||
uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0;
|
|
||||||
auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
|
|
||||||
if (RegName.empty())
|
|
||||||
return false;
|
|
||||||
raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
|
|
||||||
S << RegName;
|
|
||||||
} else if (Opcode >= dwarf::DW_OP_breg0 &&
|
|
||||||
Opcode <= dwarf::DW_OP_breg31) {
|
|
||||||
int DwarfRegNum = Opcode - dwarf::DW_OP_breg0;
|
|
||||||
int64_t Offset = Op.getRawOperand(0);
|
|
||||||
auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
|
|
||||||
if (RegName.empty())
|
|
||||||
return false;
|
|
||||||
raw_svector_ostream S(Stack.emplace_back().String);
|
|
||||||
S << RegName;
|
|
||||||
if (Offset)
|
|
||||||
S << format("%+" PRId64, Offset);
|
|
||||||
} else {
|
|
||||||
// If we hit an unknown operand, we don't know its effect on the stack,
|
|
||||||
// so bail out on the whole expression.
|
|
||||||
OS << "<unknown op " << dwarf::OperationEncodingString(Opcode) << " ("
|
|
||||||
<< (int)Opcode << ")>";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++I;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Stack.size() != 1) {
|
|
||||||
OS << "<stack of size " << Stack.size() << ", expected 1>";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Stack.front().Kind == PrintedExpr::Address)
|
|
||||||
OS << "[" << Stack.front().String << "]";
|
|
||||||
else
|
|
||||||
OS << Stack.front().String;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DWARFExpressionPrinter::printCompact(
|
|
||||||
const DWARFExpression *E, raw_ostream &OS,
|
|
||||||
std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) {
|
|
||||||
return printCompactDWARFExpr(OS, E->begin(), E->end(), GetNameForDWARFReg);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace llvm
|
|
311
llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
Normal file
311
llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
//===-- DWARFExpression.cpp -----------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
|
||||||
|
#include "llvm/ADT/SmallString.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
|
#include "llvm/Support/Format.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
using namespace dwarf;
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
typedef DWARFExpression::Operation Op;
|
||||||
|
typedef Op::Description Desc;
|
||||||
|
|
||||||
|
static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
|
||||||
|
DIDumpOptions DumpOpts,
|
||||||
|
ArrayRef<uint64_t> Operands,
|
||||||
|
unsigned Operand) {
|
||||||
|
assert(Operand < Operands.size() && "operand out of bounds");
|
||||||
|
if (!U) {
|
||||||
|
OS << format(" <base_type ref: 0x%" PRIx64 ">", Operands[Operand]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
|
||||||
|
if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
|
||||||
|
OS << " (";
|
||||||
|
if (DumpOpts.Verbose)
|
||||||
|
OS << format("0x%08" PRIx64 " -> ", Operands[Operand]);
|
||||||
|
OS << format("0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
|
||||||
|
if (auto Name = dwarf::toString(Die.find(dwarf::DW_AT_name)))
|
||||||
|
OS << " \"" << *Name << "\"";
|
||||||
|
} else {
|
||||||
|
OS << format(" <invalid base_type ref: 0x%" PRIx64 ">", Operands[Operand]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
|
||||||
|
DIDumpOptions DumpOpts, const DWARFExpression *Expr,
|
||||||
|
DWARFUnit *U) {
|
||||||
|
if (Op->isError()) {
|
||||||
|
OS << "<decoding error>";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRef Name = OperationEncodingString(Op->getCode());
|
||||||
|
assert(!Name.empty() && "DW_OP has no name!");
|
||||||
|
OS << Name;
|
||||||
|
|
||||||
|
if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) ||
|
||||||
|
(Op->getCode() >= DW_OP_reg0 && Op->getCode() <= DW_OP_reg31) ||
|
||||||
|
Op->getCode() == DW_OP_bregx || Op->getCode() == DW_OP_regx ||
|
||||||
|
Op->getCode() == DW_OP_regval_type)
|
||||||
|
if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->getCode(),
|
||||||
|
Op->getRawOperands()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (unsigned Operand = 0; Operand < Op->getDescription().Op.size();
|
||||||
|
++Operand) {
|
||||||
|
unsigned Size = Op->getDescription().Op[Operand];
|
||||||
|
unsigned Signed = Size & DWARFExpression::Operation::SignBit;
|
||||||
|
|
||||||
|
if (Size == DWARFExpression::Operation::SizeSubOpLEB) {
|
||||||
|
StringRef SubName =
|
||||||
|
SubOperationEncodingString(Op->getCode(), Op->getRawOperand(Operand));
|
||||||
|
assert(!SubName.empty() && "DW_OP SubOp has no name!");
|
||||||
|
OS << " " << SubName;
|
||||||
|
} else if (Size == DWARFExpression::Operation::BaseTypeRef && U) {
|
||||||
|
// For DW_OP_convert the operand may be 0 to indicate that conversion to
|
||||||
|
// the generic type should be done. The same holds for DW_OP_reinterpret,
|
||||||
|
// which is currently not supported.
|
||||||
|
if (Op->getCode() == DW_OP_convert && Op->getRawOperand(Operand) == 0)
|
||||||
|
OS << " 0x0";
|
||||||
|
else
|
||||||
|
prettyPrintBaseTypeRef(U, OS, DumpOpts, Op->getRawOperands(), Operand);
|
||||||
|
} else if (Size == DWARFExpression::Operation::WasmLocationArg) {
|
||||||
|
assert(Operand == 1);
|
||||||
|
switch (Op->getRawOperand(0)) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3: // global as uint32
|
||||||
|
case 4:
|
||||||
|
OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
} else if (Size == DWARFExpression::Operation::SizeBlock) {
|
||||||
|
uint64_t Offset = Op->getRawOperand(Operand);
|
||||||
|
for (unsigned i = 0; i < Op->getRawOperand(Operand - 1); ++i)
|
||||||
|
OS << format(" 0x%02x",
|
||||||
|
static_cast<uint8_t>(Expr->getData()[Offset++]));
|
||||||
|
} else {
|
||||||
|
if (Signed)
|
||||||
|
OS << format(" %+" PRId64, (int64_t)Op->getRawOperand(Operand));
|
||||||
|
else if (Op->getCode() != DW_OP_entry_value &&
|
||||||
|
Op->getCode() != DW_OP_GNU_entry_value)
|
||||||
|
OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printDwarfExpression(const DWARFExpression *E, raw_ostream &OS,
|
||||||
|
DIDumpOptions DumpOpts, DWARFUnit *U, bool IsEH) {
|
||||||
|
uint32_t EntryValExprSize = 0;
|
||||||
|
uint64_t EntryValStartOffset = 0;
|
||||||
|
if (E->getData().empty())
|
||||||
|
OS << "<empty>";
|
||||||
|
|
||||||
|
for (auto &Op : *E) {
|
||||||
|
DumpOpts.IsEH = IsEH;
|
||||||
|
if (!printOp(&Op, OS, DumpOpts, E, U)) {
|
||||||
|
uint64_t FailOffset = Op.getEndOffset();
|
||||||
|
while (FailOffset < E->getData().size())
|
||||||
|
OS << format(" %02x", static_cast<uint8_t>(E->getData()[FailOffset++]));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Op.getCode() == DW_OP_entry_value ||
|
||||||
|
Op.getCode() == DW_OP_GNU_entry_value) {
|
||||||
|
OS << "(";
|
||||||
|
EntryValExprSize = Op.getRawOperand(0);
|
||||||
|
EntryValStartOffset = Op.getEndOffset();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EntryValExprSize) {
|
||||||
|
EntryValExprSize -= Op.getEndOffset() - EntryValStartOffset;
|
||||||
|
if (EntryValExprSize == 0)
|
||||||
|
OS << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Op.getEndOffset() < E->getData().size())
|
||||||
|
OS << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A user-facing string representation of a DWARF expression. This might be an
|
||||||
|
/// Address expression, in which case it will be implicitly dereferenced, or a
|
||||||
|
/// Value expression.
|
||||||
|
struct PrintedExpr {
|
||||||
|
enum ExprKind {
|
||||||
|
Address,
|
||||||
|
Value,
|
||||||
|
};
|
||||||
|
ExprKind Kind;
|
||||||
|
SmallString<16> String;
|
||||||
|
|
||||||
|
PrintedExpr(ExprKind K = Address) : Kind(K) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool printCompactDWARFExpr(
|
||||||
|
raw_ostream &OS, DWARFExpression::iterator I,
|
||||||
|
const DWARFExpression::iterator E,
|
||||||
|
std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg =
|
||||||
|
nullptr) {
|
||||||
|
SmallVector<PrintedExpr, 4> Stack;
|
||||||
|
|
||||||
|
while (I != E) {
|
||||||
|
const DWARFExpression::Operation &Op = *I;
|
||||||
|
uint8_t Opcode = Op.getCode();
|
||||||
|
switch (Opcode) {
|
||||||
|
case dwarf::DW_OP_regx: {
|
||||||
|
// DW_OP_regx: A register, with the register num given as an operand.
|
||||||
|
// Printed as the plain register name.
|
||||||
|
uint64_t DwarfRegNum = Op.getRawOperand(0);
|
||||||
|
auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
|
||||||
|
if (RegName.empty())
|
||||||
|
return false;
|
||||||
|
raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
|
||||||
|
S << RegName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case dwarf::DW_OP_bregx: {
|
||||||
|
int DwarfRegNum = Op.getRawOperand(0);
|
||||||
|
int64_t Offset = Op.getRawOperand(1);
|
||||||
|
auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
|
||||||
|
if (RegName.empty())
|
||||||
|
return false;
|
||||||
|
raw_svector_ostream S(Stack.emplace_back().String);
|
||||||
|
S << RegName;
|
||||||
|
if (Offset)
|
||||||
|
S << format("%+" PRId64, Offset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case dwarf::DW_OP_entry_value:
|
||||||
|
case dwarf::DW_OP_GNU_entry_value: {
|
||||||
|
// DW_OP_entry_value contains a sub-expression which must be rendered
|
||||||
|
// separately.
|
||||||
|
uint64_t SubExprLength = Op.getRawOperand(0);
|
||||||
|
DWARFExpression::iterator SubExprEnd = I.skipBytes(SubExprLength);
|
||||||
|
++I;
|
||||||
|
raw_svector_ostream S(Stack.emplace_back().String);
|
||||||
|
S << "entry(";
|
||||||
|
printCompactDWARFExpr(S, I, SubExprEnd, GetNameForDWARFReg);
|
||||||
|
S << ")";
|
||||||
|
I = SubExprEnd;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case dwarf::DW_OP_stack_value: {
|
||||||
|
// The top stack entry should be treated as the actual value of tne
|
||||||
|
// variable, rather than the address of the variable in memory.
|
||||||
|
assert(!Stack.empty());
|
||||||
|
Stack.back().Kind = PrintedExpr::Value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case dwarf::DW_OP_nop: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case dwarf::DW_OP_LLVM_user: {
|
||||||
|
assert(Op.getSubCode() == dwarf::DW_OP_LLVM_nop);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) {
|
||||||
|
// DW_OP_reg<N>: A register, with the register num implied by the
|
||||||
|
// opcode. Printed as the plain register name.
|
||||||
|
uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0;
|
||||||
|
auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
|
||||||
|
if (RegName.empty())
|
||||||
|
return false;
|
||||||
|
raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
|
||||||
|
S << RegName;
|
||||||
|
} else if (Opcode >= dwarf::DW_OP_breg0 &&
|
||||||
|
Opcode <= dwarf::DW_OP_breg31) {
|
||||||
|
int DwarfRegNum = Opcode - dwarf::DW_OP_breg0;
|
||||||
|
int64_t Offset = Op.getRawOperand(0);
|
||||||
|
auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
|
||||||
|
if (RegName.empty())
|
||||||
|
return false;
|
||||||
|
raw_svector_ostream S(Stack.emplace_back().String);
|
||||||
|
S << RegName;
|
||||||
|
if (Offset)
|
||||||
|
S << format("%+" PRId64, Offset);
|
||||||
|
} else {
|
||||||
|
// If we hit an unknown operand, we don't know its effect on the stack,
|
||||||
|
// so bail out on the whole expression.
|
||||||
|
OS << "<unknown op " << dwarf::OperationEncodingString(Opcode) << " ("
|
||||||
|
<< (int)Opcode << ")>";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++I;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Stack.size() != 1) {
|
||||||
|
OS << "<stack of size " << Stack.size() << ", expected 1>";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Stack.front().Kind == PrintedExpr::Address)
|
||||||
|
OS << "[" << Stack.front().String << "]";
|
||||||
|
else
|
||||||
|
OS << Stack.front().String;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool printDwarfExpressionCompact(
|
||||||
|
const DWARFExpression *E, raw_ostream &OS,
|
||||||
|
std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) {
|
||||||
|
return printCompactDWARFExpr(OS, E->begin(), E->end(), GetNameForDWARFReg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
|
||||||
|
DIDumpOptions DumpOpts, uint8_t Opcode,
|
||||||
|
ArrayRef<uint64_t> Operands) {
|
||||||
|
if (!DumpOpts.GetNameForDWARFReg)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint64_t DwarfRegNum;
|
||||||
|
unsigned OpNum = 0;
|
||||||
|
|
||||||
|
if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
|
||||||
|
Opcode == DW_OP_regval_type)
|
||||||
|
DwarfRegNum = Operands[OpNum++];
|
||||||
|
else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
|
||||||
|
DwarfRegNum = Opcode - DW_OP_breg0;
|
||||||
|
else
|
||||||
|
DwarfRegNum = Opcode - DW_OP_reg0;
|
||||||
|
|
||||||
|
auto RegName = DumpOpts.GetNameForDWARFReg(DwarfRegNum, DumpOpts.IsEH);
|
||||||
|
if (!RegName.empty()) {
|
||||||
|
if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
|
||||||
|
Opcode == DW_OP_bregx)
|
||||||
|
OS << ' ' << RegName << format("%+" PRId64, Operands[OpNum]);
|
||||||
|
else
|
||||||
|
OS << ' ' << RegName.data();
|
||||||
|
|
||||||
|
if (Opcode == DW_OP_regval_type)
|
||||||
|
prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace llvm
|
@ -19,12 +19,12 @@
|
|||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFListTable.h"
|
#include "llvm/DebugInfo/DWARF/DWARFListTable.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFObject.h"
|
#include "llvm/DebugInfo/DWARF/DWARFObject.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Object/ObjectFile.h"
|
#include "llvm/Object/ObjectFile.h"
|
||||||
#include "llvm/Support/DataExtractor.h"
|
#include "llvm/Support/DataExtractor.h"
|
||||||
#include "llvm/Support/Errc.h"
|
#include "llvm/Support/Errc.h"
|
||||||
|
@ -19,13 +19,13 @@
|
|||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFObject.h"
|
#include "llvm/DebugInfo/DWARF/DWARFObject.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Object/Error.h"
|
#include "llvm/Object/Error.h"
|
||||||
#include "llvm/Support/DJB.h"
|
#include "llvm/Support/DJB.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
|
14
llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt
Normal file
14
llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
add_llvm_component_library(LLVMDebugInfoDWARFLowLevel
|
||||||
|
DWARFCFIProgram.cpp
|
||||||
|
DWARFExpression.cpp
|
||||||
|
|
||||||
|
ADDITIONAL_HEADER_DIRS
|
||||||
|
${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/DWARF/LowLevel
|
||||||
|
|
||||||
|
// This code should have almost no dependencies. Anything that needs
|
||||||
|
// more should use the higher-level DebugInfo/DWARF/ library.
|
||||||
|
LINK_COMPONENTS
|
||||||
|
BinaryFormat
|
||||||
|
Support
|
||||||
|
TargetParser
|
||||||
|
)
|
@ -6,9 +6,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
|
||||||
#include "llvm/DebugInfo/DIContext.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/DataExtractor.h"
|
#include "llvm/Support/DataExtractor.h"
|
||||||
#include "llvm/Support/Errc.h"
|
#include "llvm/Support/Errc.h"
|
||||||
@ -23,149 +22,6 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace dwarf;
|
using namespace dwarf;
|
||||||
|
|
||||||
// See DWARF standard v3, section 7.23
|
|
||||||
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
|
|
||||||
const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
|
|
||||||
|
|
||||||
Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset,
|
|
||||||
uint64_t EndOffset) {
|
|
||||||
DataExtractor::Cursor C(*Offset);
|
|
||||||
while (C && C.tell() < EndOffset) {
|
|
||||||
uint8_t Opcode = Data.getRelocatedValue(C, 1);
|
|
||||||
if (!C)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Some instructions have a primary opcode encoded in the top bits.
|
|
||||||
if (uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) {
|
|
||||||
// If it's a primary opcode, the first operand is encoded in the bottom
|
|
||||||
// bits of the opcode itself.
|
|
||||||
uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
|
|
||||||
switch (Primary) {
|
|
||||||
case DW_CFA_advance_loc:
|
|
||||||
case DW_CFA_restore:
|
|
||||||
addInstruction(Primary, Op1);
|
|
||||||
break;
|
|
||||||
case DW_CFA_offset:
|
|
||||||
addInstruction(Primary, Op1, Data.getULEB128(C));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
llvm_unreachable("invalid primary CFI opcode");
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extended opcode - its value is Opcode itself.
|
|
||||||
switch (Opcode) {
|
|
||||||
default:
|
|
||||||
return createStringError(errc::illegal_byte_sequence,
|
|
||||||
"invalid extended CFI opcode 0x%" PRIx8, Opcode);
|
|
||||||
case DW_CFA_nop:
|
|
||||||
case DW_CFA_remember_state:
|
|
||||||
case DW_CFA_restore_state:
|
|
||||||
case DW_CFA_GNU_window_save:
|
|
||||||
case DW_CFA_AARCH64_negate_ra_state_with_pc:
|
|
||||||
// No operands
|
|
||||||
addInstruction(Opcode);
|
|
||||||
break;
|
|
||||||
case DW_CFA_set_loc:
|
|
||||||
// Operands: Address
|
|
||||||
addInstruction(Opcode, Data.getRelocatedAddress(C));
|
|
||||||
break;
|
|
||||||
case DW_CFA_advance_loc1:
|
|
||||||
// Operands: 1-byte delta
|
|
||||||
addInstruction(Opcode, Data.getRelocatedValue(C, 1));
|
|
||||||
break;
|
|
||||||
case DW_CFA_advance_loc2:
|
|
||||||
// Operands: 2-byte delta
|
|
||||||
addInstruction(Opcode, Data.getRelocatedValue(C, 2));
|
|
||||||
break;
|
|
||||||
case DW_CFA_advance_loc4:
|
|
||||||
// Operands: 4-byte delta
|
|
||||||
addInstruction(Opcode, Data.getRelocatedValue(C, 4));
|
|
||||||
break;
|
|
||||||
case DW_CFA_restore_extended:
|
|
||||||
case DW_CFA_undefined:
|
|
||||||
case DW_CFA_same_value:
|
|
||||||
case DW_CFA_def_cfa_register:
|
|
||||||
case DW_CFA_def_cfa_offset:
|
|
||||||
case DW_CFA_GNU_args_size:
|
|
||||||
// Operands: ULEB128
|
|
||||||
addInstruction(Opcode, Data.getULEB128(C));
|
|
||||||
break;
|
|
||||||
case DW_CFA_def_cfa_offset_sf:
|
|
||||||
// Operands: SLEB128
|
|
||||||
addInstruction(Opcode, Data.getSLEB128(C));
|
|
||||||
break;
|
|
||||||
case DW_CFA_LLVM_def_aspace_cfa:
|
|
||||||
case DW_CFA_LLVM_def_aspace_cfa_sf: {
|
|
||||||
auto RegNum = Data.getULEB128(C);
|
|
||||||
auto CfaOffset = Opcode == DW_CFA_LLVM_def_aspace_cfa
|
|
||||||
? Data.getULEB128(C)
|
|
||||||
: Data.getSLEB128(C);
|
|
||||||
auto AddressSpace = Data.getULEB128(C);
|
|
||||||
addInstruction(Opcode, RegNum, CfaOffset, AddressSpace);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DW_CFA_offset_extended:
|
|
||||||
case DW_CFA_register:
|
|
||||||
case DW_CFA_def_cfa:
|
|
||||||
case DW_CFA_val_offset: {
|
|
||||||
// Operands: ULEB128, ULEB128
|
|
||||||
// Note: We can not embed getULEB128 directly into function
|
|
||||||
// argument list. getULEB128 changes Offset and order of evaluation
|
|
||||||
// for arguments is unspecified.
|
|
||||||
uint64_t op1 = Data.getULEB128(C);
|
|
||||||
uint64_t op2 = Data.getULEB128(C);
|
|
||||||
addInstruction(Opcode, op1, op2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DW_CFA_offset_extended_sf:
|
|
||||||
case DW_CFA_def_cfa_sf:
|
|
||||||
case DW_CFA_val_offset_sf: {
|
|
||||||
// Operands: ULEB128, SLEB128
|
|
||||||
// Note: see comment for the previous case
|
|
||||||
uint64_t op1 = Data.getULEB128(C);
|
|
||||||
uint64_t op2 = (uint64_t)Data.getSLEB128(C);
|
|
||||||
addInstruction(Opcode, op1, op2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DW_CFA_def_cfa_expression: {
|
|
||||||
uint64_t ExprLength = Data.getULEB128(C);
|
|
||||||
addInstruction(Opcode, 0);
|
|
||||||
StringRef Expression = Data.getBytes(C, ExprLength);
|
|
||||||
|
|
||||||
DataExtractor Extractor(Expression, Data.isLittleEndian(),
|
|
||||||
Data.getAddressSize());
|
|
||||||
// Note. We do not pass the DWARF format to DWARFExpression, because
|
|
||||||
// DW_OP_call_ref, the only operation which depends on the format, is
|
|
||||||
// prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
|
|
||||||
Instructions.back().Expression =
|
|
||||||
DWARFExpression(Extractor, Data.getAddressSize());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DW_CFA_expression:
|
|
||||||
case DW_CFA_val_expression: {
|
|
||||||
uint64_t RegNum = Data.getULEB128(C);
|
|
||||||
addInstruction(Opcode, RegNum, 0);
|
|
||||||
|
|
||||||
uint64_t BlockLength = Data.getULEB128(C);
|
|
||||||
StringRef Expression = Data.getBytes(C, BlockLength);
|
|
||||||
DataExtractor Extractor(Expression, Data.isLittleEndian(),
|
|
||||||
Data.getAddressSize());
|
|
||||||
// Note. We do not pass the DWARF format to DWARFExpression, because
|
|
||||||
// DW_OP_call_ref, the only operation which depends on the format, is
|
|
||||||
// prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
|
|
||||||
Instructions.back().Expression =
|
|
||||||
DWARFExpression(Extractor, Data.getAddressSize());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*Offset = C.tell();
|
|
||||||
return C.takeError();
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRef CFIProgram::callFrameString(unsigned Opcode) const {
|
StringRef CFIProgram::callFrameString(unsigned Opcode) const {
|
||||||
return dwarf::CallFrameString(Opcode, Arch);
|
return dwarf::CallFrameString(Opcode, Arch);
|
||||||
}
|
}
|
253
llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp
Normal file
253
llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
//===-- DWARFExpression.cpp -----------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
|
#include "llvm/ADT/SmallString.h"
|
||||||
|
#include "llvm/Support/Format.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
using namespace dwarf;
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
typedef DWARFExpression::Operation Op;
|
||||||
|
typedef Op::Description Desc;
|
||||||
|
|
||||||
|
static std::vector<Desc> getOpDescriptions() {
|
||||||
|
std::vector<Desc> Descriptions;
|
||||||
|
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_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);
|
||||||
|
Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2);
|
||||||
|
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::Dwarf4, Op::SizeLEB, Op::SizeBlock);
|
||||||
|
Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf4);
|
||||||
|
Descriptions[DW_OP_implicit_pointer] =
|
||||||
|
Desc(Op::Dwarf5, Op::SizeRefAddr, Op::SignedSizeLEB);
|
||||||
|
Descriptions[DW_OP_addrx] = Desc(Op::Dwarf5, Op::SizeLEB);
|
||||||
|
Descriptions[DW_OP_constx] = Desc(Op::Dwarf5, Op::SizeLEB);
|
||||||
|
Descriptions[DW_OP_entry_value] = Desc(Op::Dwarf5, Op::SizeLEB);
|
||||||
|
Descriptions[DW_OP_convert] = Desc(Op::Dwarf5, Op::BaseTypeRef);
|
||||||
|
Descriptions[DW_OP_regval_type] =
|
||||||
|
Desc(Op::Dwarf5, Op::SizeLEB, Op::BaseTypeRef);
|
||||||
|
Descriptions[DW_OP_WASM_location] =
|
||||||
|
Desc(Op::Dwarf4, Op::SizeLEB, Op::WasmLocationArg);
|
||||||
|
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);
|
||||||
|
Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB);
|
||||||
|
Descriptions[DW_OP_GNU_implicit_pointer] =
|
||||||
|
Desc(Op::Dwarf4, Op::SizeRefAddr, Op::SignedSizeLEB);
|
||||||
|
// This Description acts as a marker that getSubOpDesc must be called
|
||||||
|
// to fetch the final Description for the operation. Each such final
|
||||||
|
// Description must share the same first SizeSubOpLEB operand.
|
||||||
|
Descriptions[DW_OP_LLVM_user] = Desc(Op::Dwarf5, Op::SizeSubOpLEB);
|
||||||
|
return Descriptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Desc getDescImpl(ArrayRef<Desc> Descriptions, unsigned Opcode) {
|
||||||
|
// Handle possible corrupted or unsupported operation.
|
||||||
|
if (Opcode >= Descriptions.size())
|
||||||
|
return {};
|
||||||
|
return Descriptions[Opcode];
|
||||||
|
}
|
||||||
|
|
||||||
|
static Desc getOpDesc(unsigned Opcode) {
|
||||||
|
static std::vector<Desc> Descriptions = getOpDescriptions();
|
||||||
|
return getDescImpl(Descriptions, Opcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<Desc> getSubOpDescriptions() {
|
||||||
|
static constexpr unsigned LlvmUserDescriptionsSize = 1
|
||||||
|
#define HANDLE_DW_OP_LLVM_USEROP(ID, NAME) +1
|
||||||
|
#include "llvm/BinaryFormat/Dwarf.def"
|
||||||
|
;
|
||||||
|
std::vector<Desc> Descriptions;
|
||||||
|
Descriptions.resize(LlvmUserDescriptionsSize);
|
||||||
|
Descriptions[DW_OP_LLVM_nop] = Desc(Op::Dwarf5, Op::SizeSubOpLEB);
|
||||||
|
return Descriptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Desc getSubOpDesc(unsigned Opcode, unsigned SubOpcode) {
|
||||||
|
assert(Opcode == DW_OP_LLVM_user);
|
||||||
|
static std::vector<Desc> Descriptions = getSubOpDescriptions();
|
||||||
|
return getDescImpl(Descriptions, SubOpcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DWARFExpression::Operation::extract(DataExtractor Data,
|
||||||
|
uint8_t AddressSize, uint64_t Offset,
|
||||||
|
std::optional<DwarfFormat> Format) {
|
||||||
|
EndOffset = Offset;
|
||||||
|
Opcode = Data.getU8(&Offset);
|
||||||
|
|
||||||
|
Desc = getOpDesc(Opcode);
|
||||||
|
if (Desc.Version == Operation::DwarfNA)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Operands.resize(Desc.Op.size());
|
||||||
|
OperandEndOffsets.resize(Desc.Op.size());
|
||||||
|
for (unsigned Operand = 0; Operand < Desc.Op.size(); ++Operand) {
|
||||||
|
unsigned Size = Desc.Op[Operand];
|
||||||
|
unsigned Signed = Size & Operation::SignBit;
|
||||||
|
|
||||||
|
switch (Size & ~Operation::SignBit) {
|
||||||
|
case Operation::SizeSubOpLEB:
|
||||||
|
assert(Operand == 0 && "SubOp operand must be the first operand");
|
||||||
|
Operands[Operand] = Data.getULEB128(&Offset);
|
||||||
|
Desc = getSubOpDesc(Opcode, Operands[Operand]);
|
||||||
|
if (Desc.Version == Operation::DwarfNA)
|
||||||
|
return false;
|
||||||
|
assert(Desc.Op[Operand] == Operation::SizeSubOpLEB &&
|
||||||
|
"SizeSubOpLEB Description must begin with SizeSubOpLEB operand");
|
||||||
|
break;
|
||||||
|
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:
|
||||||
|
Operands[Operand] = Data.getUnsigned(&Offset, AddressSize);
|
||||||
|
break;
|
||||||
|
case Operation::SizeRefAddr:
|
||||||
|
if (!Format)
|
||||||
|
return false;
|
||||||
|
Operands[Operand] =
|
||||||
|
Data.getUnsigned(&Offset, dwarf::getDwarfOffsetByteSize(*Format));
|
||||||
|
break;
|
||||||
|
case Operation::SizeLEB:
|
||||||
|
if (Signed)
|
||||||
|
Operands[Operand] = Data.getSLEB128(&Offset);
|
||||||
|
else
|
||||||
|
Operands[Operand] = Data.getULEB128(&Offset);
|
||||||
|
break;
|
||||||
|
case Operation::BaseTypeRef:
|
||||||
|
Operands[Operand] = Data.getULEB128(&Offset);
|
||||||
|
break;
|
||||||
|
case Operation::WasmLocationArg:
|
||||||
|
assert(Operand == 1);
|
||||||
|
switch (Operands[0]) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
Operands[Operand] = Data.getULEB128(&Offset);
|
||||||
|
break;
|
||||||
|
case 3: // global as uint32
|
||||||
|
Operands[Operand] = Data.getU32(&Offset);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false; // Unknown Wasm location
|
||||||
|
}
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
OperandEndOffsets[Operand] = Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
EndOffset = Offset;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<unsigned> DWARFExpression::Operation::getSubCode() const {
|
||||||
|
if (!Desc.Op.size() || Desc.Op[0] != Operation::SizeSubOpLEB)
|
||||||
|
return std::nullopt;
|
||||||
|
return Operands[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DWARFExpression::operator==(const DWARFExpression &RHS) const {
|
||||||
|
if (AddressSize != RHS.AddressSize || Format != RHS.Format)
|
||||||
|
return false;
|
||||||
|
return Data.getData() == RHS.Data.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace llvm
|
@ -47,7 +47,8 @@ add_llvm_component_library(LLVMDebugInfoLogicalView
|
|||||||
MC
|
MC
|
||||||
Support
|
Support
|
||||||
TargetParser
|
TargetParser
|
||||||
DebugInfoDWARF
|
|
||||||
DebugInfoCodeView
|
DebugInfoCodeView
|
||||||
|
DebugInfoDWARF
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
DebugInfoPDB
|
DebugInfoPDB
|
||||||
)
|
)
|
||||||
|
@ -14,7 +14,8 @@
|
|||||||
#include "llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h"
|
#include "llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h"
|
||||||
#include "llvm/DebugInfo/DIContext.h"
|
#include "llvm/DebugInfo/DIContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
|
#include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
|
||||||
#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
|
#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
|
||||||
#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
|
#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
|
||||||
@ -594,8 +595,7 @@ std::string LVDWARFReader::getRegisterName(LVSmall Opcode,
|
|||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
DumpOpts.GetNameForDWARFReg = GetRegName;
|
DumpOpts.GetNameForDWARFReg = GetRegName;
|
||||||
DWARFExpressionPrinter::prettyPrintRegisterOp(/*U=*/nullptr, Stream, DumpOpts,
|
prettyPrintRegisterOp(/*U=*/nullptr, Stream, DumpOpts, Opcode, Operands);
|
||||||
Opcode, Operands);
|
|
||||||
return Stream.str();
|
return Stream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ add_llvm_component_library(LLVMProfileData
|
|||||||
Demangle
|
Demangle
|
||||||
Symbolize
|
Symbolize
|
||||||
DebugInfoDWARF
|
DebugInfoDWARF
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
TargetParser
|
TargetParser
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
#include "llvm/DebugInfo/DIContext.h"
|
#include "llvm/DebugInfo/DIContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Object/MachO.h"
|
#include "llvm/Object/MachO.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/Format.h"
|
#include "llvm/Support/Format.h"
|
||||||
|
@ -15,6 +15,7 @@ set(LLVM_LINK_COMPONENTS
|
|||||||
DWARFLinkerClassic
|
DWARFLinkerClassic
|
||||||
DWARFLinkerParallel
|
DWARFLinkerParallel
|
||||||
DebugInfoDWARF
|
DebugInfoDWARF
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
MC
|
MC
|
||||||
Object
|
Object
|
||||||
Option
|
Option
|
||||||
|
@ -39,10 +39,10 @@
|
|||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/MC/MCAsmBackend.h"
|
#include "llvm/MC/MCAsmBackend.h"
|
||||||
#include "llvm/MC/MCAsmInfo.h"
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
#include "llvm/MC/MCCodeEmitter.h"
|
#include "llvm/MC/MCCodeEmitter.h"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
set(LLVM_LINK_COMPONENTS
|
set(LLVM_LINK_COMPONENTS
|
||||||
DebugInfoDWARF
|
DebugInfoDWARF
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
AllTargetsDescs
|
AllTargetsDescs
|
||||||
AllTargetsInfos
|
AllTargetsInfos
|
||||||
MC
|
MC
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "llvm/ADT/StringSet.h"
|
#include "llvm/ADT/StringSet.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Object/ObjectFile.h"
|
#include "llvm/Object/ObjectFile.h"
|
||||||
#include "llvm/Support/JSON.h"
|
#include "llvm/Support/JSON.h"
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ set(LLVM_LINK_COMPONENTS
|
|||||||
DWARFLinkerClassic
|
DWARFLinkerClassic
|
||||||
DWARFLinkerParallel
|
DWARFLinkerParallel
|
||||||
DebugInfoDWARF
|
DebugInfoDWARF
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
MC
|
MC
|
||||||
ObjCopy
|
ObjCopy
|
||||||
Object
|
Object
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include "llvm/DWARFLinker/Classic/DWARFStreamer.h"
|
#include "llvm/DWARFLinker/Classic/DWARFStreamer.h"
|
||||||
#include "llvm/DWARFLinker/Parallel/DWARFLinker.h"
|
#include "llvm/DWARFLinker/Parallel/DWARFLinker.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Object/ObjectFile.h"
|
#include "llvm/Object/ObjectFile.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
|
|||||||
BinaryFormat
|
BinaryFormat
|
||||||
DebugInfoBTF
|
DebugInfoBTF
|
||||||
DebugInfoDWARF
|
DebugInfoDWARF
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
Demangle
|
Demangle
|
||||||
MC
|
MC
|
||||||
MCDisassembler
|
MCDisassembler
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
#include "SourcePrinter.h"
|
#include "SourcePrinter.h"
|
||||||
#include "llvm-objdump.h"
|
#include "llvm-objdump.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/Support/FormatVariadic.h"
|
#include "llvm/Support/FormatVariadic.h"
|
||||||
|
|
||||||
#define DEBUG_TYPE "objdump"
|
#define DEBUG_TYPE "objdump"
|
||||||
@ -45,7 +46,7 @@ void LiveVariable::print(raw_ostream &OS, const MCRegisterInfo &MRI) const {
|
|||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
DWARFExpressionPrinter::printCompact(&Expression, OS, GetRegName);
|
printDwarfExpressionCompact(&Expression, OS, GetRegName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LiveVariablePrinter::addVariable(DWARFDie FuncDie, DWARFDie VarDie) {
|
void LiveVariablePrinter::addVariable(DWARFDie FuncDie, DWARFDie VarDie) {
|
||||||
|
@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
|
|||||||
BinaryFormat
|
BinaryFormat
|
||||||
CodeGenTypes
|
CodeGenTypes
|
||||||
DebugInfoDWARF
|
DebugInfoDWARF
|
||||||
|
DebugInfoDWARFLowLevel
|
||||||
MC
|
MC
|
||||||
Object
|
Object
|
||||||
ObjectYAML
|
ObjectYAML
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/MC/MCInstrInfo.h"
|
#include "llvm/MC/MCInstrInfo.h"
|
||||||
#include "llvm/MC/MCRegisterInfo.h"
|
#include "llvm/MC/MCRegisterInfo.h"
|
||||||
#include "llvm/MC/TargetRegistry.h"
|
#include "llvm/MC/TargetRegistry.h"
|
||||||
@ -70,7 +71,7 @@ void DWARFExpressionCompactPrinterTest::TestExprPrinter(
|
|||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
DWARFExpressionPrinter::printCompact(&Expr, OS, GetRegName);
|
printDwarfExpressionCompact(&Expr, OS, GetRegName);
|
||||||
EXPECT_EQ(OS.str(), Expected);
|
EXPECT_EQ(OS.str(), Expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
|
||||||
#include "llvm/MC/MCAsmBackend.h"
|
#include "llvm/MC/MCAsmBackend.h"
|
||||||
#include "llvm/MC/MCAsmInfo.h"
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
#include "llvm/MC/MCCodeEmitter.h"
|
#include "llvm/MC/MCCodeEmitter.h"
|
||||||
|
@ -106,6 +106,7 @@ cc_library(
|
|||||||
"//llvm:DWARFLinker",
|
"//llvm:DWARFLinker",
|
||||||
"//llvm:DWP",
|
"//llvm:DWP",
|
||||||
"//llvm:DebugInfoDWARF",
|
"//llvm:DebugInfoDWARF",
|
||||||
|
"//llvm:DebugInfoDWARFLowLevel",
|
||||||
"//llvm:Demangle",
|
"//llvm:Demangle",
|
||||||
"//llvm:JITLink",
|
"//llvm:JITLink",
|
||||||
"//llvm:MC",
|
"//llvm:MC",
|
||||||
@ -296,6 +297,7 @@ cc_library(
|
|||||||
"//llvm:BinaryFormat",
|
"//llvm:BinaryFormat",
|
||||||
"//llvm:CodeGen",
|
"//llvm:CodeGen",
|
||||||
"//llvm:DebugInfoDWARF",
|
"//llvm:DebugInfoDWARF",
|
||||||
|
"//llvm:DebugInfoDWARFLowLevel",
|
||||||
"//llvm:Demangle",
|
"//llvm:Demangle",
|
||||||
"//llvm:ExecutionEngine",
|
"//llvm:ExecutionEngine",
|
||||||
"//llvm:MC",
|
"//llvm:MC",
|
||||||
|
@ -493,6 +493,7 @@ cc_library(
|
|||||||
":DebugInfo",
|
":DebugInfo",
|
||||||
":DebugInfoCodeView",
|
":DebugInfoCodeView",
|
||||||
":DebugInfoDWARF",
|
":DebugInfoDWARF",
|
||||||
|
":DebugInfoDWARFLowLevel",
|
||||||
":DebugInfoPDB",
|
":DebugInfoPDB",
|
||||||
":Demangle",
|
":Demangle",
|
||||||
":MC",
|
":MC",
|
||||||
@ -572,6 +573,7 @@ cc_library(
|
|||||||
deps = [
|
deps = [
|
||||||
":BinaryFormat",
|
":BinaryFormat",
|
||||||
":DebugInfo",
|
":DebugInfo",
|
||||||
|
":DebugInfoDWARFLowLevel",
|
||||||
":MC",
|
":MC",
|
||||||
":Object",
|
":Object",
|
||||||
":Support",
|
":Support",
|
||||||
@ -579,6 +581,20 @@ cc_library(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "DebugInfoDWARFLowLevel",
|
||||||
|
srcs = glob([
|
||||||
|
"lib/DebugInfo/DWARF/LowLevel/*.cpp",
|
||||||
|
]),
|
||||||
|
hdrs = glob(["include/llvm/DebugInfo/DWARF/LowLevel/*.h"]),
|
||||||
|
copts = llvm_copts,
|
||||||
|
deps = [
|
||||||
|
":BinaryFormat",
|
||||||
|
":Support",
|
||||||
|
":TargetParser",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "DebugInfoGSYM",
|
name = "DebugInfoGSYM",
|
||||||
srcs = glob([
|
srcs = glob([
|
||||||
@ -1163,6 +1179,7 @@ cc_library(
|
|||||||
":Core",
|
":Core",
|
||||||
":DebugInfo",
|
":DebugInfo",
|
||||||
":DebugInfoDWARF",
|
":DebugInfoDWARF",
|
||||||
|
":DebugInfoDWARFLowLevel",
|
||||||
":Demangle",
|
":Demangle",
|
||||||
":Object",
|
":Object",
|
||||||
":Support",
|
":Support",
|
||||||
@ -2090,6 +2107,7 @@ cc_library(
|
|||||||
":Core",
|
":Core",
|
||||||
":DebugInfoCodeView",
|
":DebugInfoCodeView",
|
||||||
":DebugInfoDWARF",
|
":DebugInfoDWARF",
|
||||||
|
":DebugInfoDWARFLowLevel",
|
||||||
":IPO",
|
":IPO",
|
||||||
":IRPrinter",
|
":IRPrinter",
|
||||||
":Instrumentation",
|
":Instrumentation",
|
||||||
@ -3231,6 +3249,7 @@ cc_library(
|
|||||||
":CodeGenTypes",
|
":CodeGenTypes",
|
||||||
":DWARFLinkerBase",
|
":DWARFLinkerBase",
|
||||||
":DebugInfoDWARF",
|
":DebugInfoDWARF",
|
||||||
|
":DebugInfoDWARFLowLevel",
|
||||||
":MC",
|
":MC",
|
||||||
":Support",
|
":Support",
|
||||||
":Target",
|
":Target",
|
||||||
@ -3249,6 +3268,7 @@ cc_library(
|
|||||||
":BinaryFormat",
|
":BinaryFormat",
|
||||||
":CodeGen",
|
":CodeGen",
|
||||||
":DebugInfoDWARF",
|
":DebugInfoDWARF",
|
||||||
|
":DebugInfoDWARFLowLevel",
|
||||||
":Support",
|
":Support",
|
||||||
":Target",
|
":Target",
|
||||||
],
|
],
|
||||||
@ -3549,6 +3569,7 @@ cc_library(
|
|||||||
":DWARFLinkerParallel",
|
":DWARFLinkerParallel",
|
||||||
":DebugInfo",
|
":DebugInfo",
|
||||||
":DebugInfoDWARF",
|
":DebugInfoDWARF",
|
||||||
|
":DebugInfoDWARFLowLevel",
|
||||||
":DsymutilTableGen",
|
":DsymutilTableGen",
|
||||||
":MC",
|
":MC",
|
||||||
":Object",
|
":Object",
|
||||||
@ -3966,6 +3987,7 @@ cc_binary(
|
|||||||
":BinaryFormat",
|
":BinaryFormat",
|
||||||
":DebugInfo",
|
":DebugInfo",
|
||||||
":DebugInfoDWARF",
|
":DebugInfoDWARF",
|
||||||
|
":DebugInfoDWARFLowLevel",
|
||||||
":MC",
|
":MC",
|
||||||
":Object",
|
":Object",
|
||||||
":Support",
|
":Support",
|
||||||
@ -3997,6 +4019,7 @@ cc_binary(
|
|||||||
":DWARFLinker",
|
":DWARFLinker",
|
||||||
":DWARFLinkerParallel",
|
":DWARFLinkerParallel",
|
||||||
":DebugInfoDWARF",
|
":DebugInfoDWARF",
|
||||||
|
":DebugInfoDWARFLowLevel",
|
||||||
":DwarfutilOptionsTableGen",
|
":DwarfutilOptionsTableGen",
|
||||||
":MC",
|
":MC",
|
||||||
":ObjCopy",
|
":ObjCopy",
|
||||||
@ -4614,6 +4637,7 @@ cc_library(
|
|||||||
":DebugInfo",
|
":DebugInfo",
|
||||||
":DebugInfoBTF",
|
":DebugInfoBTF",
|
||||||
":DebugInfoDWARF",
|
":DebugInfoDWARF",
|
||||||
|
":DebugInfoDWARFLowLevel",
|
||||||
":Debuginfod",
|
":Debuginfod",
|
||||||
":Demangle",
|
":Demangle",
|
||||||
":MC",
|
":MC",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user