[Lldb-commits] [lldb] a2fb705 - Revert "[lldb] Add cast to fix compile error on 32-bit platforms"
Sylvestre Ledru via lldb-commits
lldb-commits at lists.llvm.org
Tue Dec 10 15:02:57 PST 2024
Author: Sylvestre Ledru
Date: 2024-12-11T00:00:44+01:00
New Revision: a2fb70523ac310af6d8a4d9663dfe7c9cd370c53
URL: https://github.com/llvm/llvm-project/commit/a2fb70523ac310af6d8a4d9663dfe7c9cd370c53
DIFF: https://github.com/llvm/llvm-project/commit/a2fb70523ac310af6d8a4d9663dfe7c9cd370c53.diff
LOG: Revert "[lldb] Add cast to fix compile error on 32-bit platforms"
This reverts commit f6012a209dca6b1866d00e6b4f96279469884320.
Revert "[lldb] Add cast to fix compile error on 32-but platforms"
This reverts commit d300337e93da4ed96b044557e4b0a30001967cf0.
Revert "[lldb] Improve log message to include missing strings"
This reverts commit 0be33484853557bc0fd9dfb94e0b6c15dda136ce.
Revert "[lldb] Add comment"
This reverts commit e2bb47443d2e5c022c7851dd6029e3869fc8835c.
Revert "[lldb] Implement a formatter bytecode interpreter in C++"
This reverts commit 9a9c1d4a6155a96ce9be494cec7e25731d36b33e.
Added:
Modified:
lldb/include/lldb/DataFormatters/FormattersHelpers.h
lldb/include/lldb/DataFormatters/TypeSummary.h
lldb/include/lldb/lldb-enumerations.h
lldb/source/API/SBTypeSummary.cpp
lldb/source/Core/Section.cpp
lldb/source/DataFormatters/CMakeLists.txt
lldb/source/DataFormatters/TypeSummary.cpp
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
lldb/source/Symbol/ObjectFile.cpp
lldb/source/Target/Target.cpp
lldb/unittests/DataFormatter/CMakeLists.txt
Removed:
lldb/include/lldb/DataFormatters/FormatterSection.h
lldb/source/DataFormatters/FormatterBytecode.cpp
lldb/source/DataFormatters/FormatterBytecode.def
lldb/source/DataFormatters/FormatterBytecode.h
lldb/source/DataFormatters/FormatterSection.cpp
lldb/test/API/functionalities/data-formatter/bytecode-summary/Makefile
lldb/test/API/functionalities/data-formatter/bytecode-summary/TestBytecodeSummary.py
lldb/test/API/functionalities/data-formatter/bytecode-summary/main.cpp
lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp
################################################################################
diff --git a/lldb/include/lldb/DataFormatters/FormatterSection.h b/lldb/include/lldb/DataFormatters/FormatterSection.h
deleted file mode 100644
index 0613fba6c3a602..00000000000000
--- a/lldb/include/lldb/DataFormatters/FormatterSection.h
+++ /dev/null
@@ -1,26 +0,0 @@
-//===-- FormattersSection.h -------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_DATAFORMATTERS_FORMATTERSECTION_H
-#define LLDB_DATAFORMATTERS_FORMATTERSECTION_H
-
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-forward.h"
-
-namespace lldb_private {
-/// Load type summaries embedded in the binary. These are type summaries
-/// provided by the authors of the code.
-void LoadTypeSummariesForModule(lldb::ModuleSP module_sp);
-
-/// Load data formatters embedded in the binary. These are formatters provided
-/// by the authors of the code using LLDB formatter bytecode.
-void LoadFormattersForModule(lldb::ModuleSP module_sp);
-
-} // namespace lldb_private
-
-#endif // LLDB_DATAFORMATTERS_FORMATTERSECTION_H
diff --git a/lldb/include/lldb/DataFormatters/FormattersHelpers.h b/lldb/include/lldb/DataFormatters/FormattersHelpers.h
index a98042fd40f93a..a2e8521d96651b 100644
--- a/lldb/include/lldb/DataFormatters/FormattersHelpers.h
+++ b/lldb/include/lldb/DataFormatters/FormattersHelpers.h
@@ -1,4 +1,5 @@
-//===-- FormattersHelpers.h -------------------------------------*- C++ -*-===//
+//===-- FormattersHelpers.h --------------------------------------*- C++
+//-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/include/lldb/DataFormatters/TypeSummary.h b/lldb/include/lldb/DataFormatters/TypeSummary.h
index f4d5563516ecb8..382824aa2813da 100644
--- a/lldb/include/lldb/DataFormatters/TypeSummary.h
+++ b/lldb/include/lldb/DataFormatters/TypeSummary.h
@@ -22,10 +22,6 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StructuredData.h"
-namespace llvm {
-class MemoryBuffer;
-}
-
namespace lldb_private {
class TypeSummaryOptions {
public:
@@ -48,7 +44,7 @@ class TypeSummaryOptions {
class TypeSummaryImpl {
public:
- enum class Kind { eSummaryString, eScript, eBytecode, eCallback, eInternal };
+ enum class Kind { eSummaryString, eScript, eCallback, eInternal };
virtual ~TypeSummaryImpl() = default;
@@ -413,23 +409,6 @@ struct ScriptSummaryFormat : public TypeSummaryImpl {
ScriptSummaryFormat(const ScriptSummaryFormat &) = delete;
const ScriptSummaryFormat &operator=(const ScriptSummaryFormat &) = delete;
};
-
-/// A summary formatter that is defined in LLDB formmater bytecode.
-class BytecodeSummaryFormat : public TypeSummaryImpl {
- std::unique_ptr<llvm::MemoryBuffer> m_bytecode;
-
-public:
- BytecodeSummaryFormat(const TypeSummaryImpl::Flags &flags,
- std::unique_ptr<llvm::MemoryBuffer> bytecode);
- bool FormatObject(ValueObject *valobj, std::string &dest,
- const TypeSummaryOptions &options) override;
- std::string GetDescription() override;
- std::string GetName() override;
- static bool classof(const TypeSummaryImpl *S) {
- return S->GetKind() == Kind::eBytecode;
- }
-};
-
} // namespace lldb_private
#endif // LLDB_DATAFORMATTERS_TYPESUMMARY_H
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index 0094fcd596fdf7..e00ec7f17c5cb8 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -764,7 +764,6 @@ enum SectionType {
eSectionTypeDWARFDebugTuIndex,
eSectionTypeCTF,
eSectionTypeLLDBTypeSummaries,
- eSectionTypeLLDBFormatters,
eSectionTypeSwiftModules,
};
diff --git a/lldb/source/API/SBTypeSummary.cpp b/lldb/source/API/SBTypeSummary.cpp
index 856ee0ed3175b3..a5e87188c9f630 100644
--- a/lldb/source/API/SBTypeSummary.cpp
+++ b/lldb/source/API/SBTypeSummary.cpp
@@ -343,7 +343,6 @@ bool SBTypeSummary::IsEqualTo(lldb::SBTypeSummary &rhs) {
case TypeSummaryImpl::Kind::eCallback:
return llvm::dyn_cast<CXXFunctionSummaryFormat>(m_opaque_sp.get()) ==
llvm::dyn_cast<CXXFunctionSummaryFormat>(rhs.m_opaque_sp.get());
- case TypeSummaryImpl::Kind::eBytecode:
case TypeSummaryImpl::Kind::eScript:
if (IsFunctionCode() != rhs.IsFunctionCode())
return false;
diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp
index 31273ede618f21..ee01b4ce06ca1e 100644
--- a/lldb/source/Core/Section.cpp
+++ b/lldb/source/Core/Section.cpp
@@ -149,12 +149,10 @@ const char *Section::GetTypeAsCString() const {
return "ctf";
case eSectionTypeLLDBTypeSummaries:
return "lldb-type-summaries";
- case eSectionTypeLLDBFormatters:
- return "lldb-formatters";
- case eSectionTypeSwiftModules:
- return "swift-modules";
case eSectionTypeOther:
return "regular";
+ case eSectionTypeSwiftModules:
+ return "swift-modules";
}
return "unknown";
}
@@ -462,7 +460,6 @@ bool Section::ContainsOnlyDebugInfo() const {
case eSectionTypeDWARFGNUDebugAltLink:
case eSectionTypeCTF:
case eSectionTypeLLDBTypeSummaries:
- case eSectionTypeLLDBFormatters:
case eSectionTypeSwiftModules:
return true;
}
diff --git a/lldb/source/DataFormatters/CMakeLists.txt b/lldb/source/DataFormatters/CMakeLists.txt
index 91b10ba9e0ac8b..13faf65227d2c9 100644
--- a/lldb/source/DataFormatters/CMakeLists.txt
+++ b/lldb/source/DataFormatters/CMakeLists.txt
@@ -5,9 +5,7 @@ add_lldb_library(lldbDataFormatters NO_PLUGIN_DEPENDENCIES
FormatCache.cpp
FormatClasses.cpp
FormatManager.cpp
- FormatterBytecode.cpp
FormattersHelpers.cpp
- FormatterSection.cpp
LanguageCategory.cpp
StringPrinter.cpp
TypeCategory.cpp
diff --git a/lldb/source/DataFormatters/FormatterBytecode.cpp b/lldb/source/DataFormatters/FormatterBytecode.cpp
deleted file mode 100644
index 21e90e75202f68..00000000000000
--- a/lldb/source/DataFormatters/FormatterBytecode.cpp
+++ /dev/null
@@ -1,575 +0,0 @@
-//===-- FormatterBytecode.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 "FormatterBytecode.h"
-#include "lldb/Utility/LLDBLog.h"
-#include "lldb/ValueObject/ValueObject.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/FormatProviders.h"
-#include "llvm/Support/FormatVariadicDetails.h"
-
-using namespace lldb;
-namespace lldb_private {
-
-std::string toString(FormatterBytecode::OpCodes op) {
- switch (op) {
-#define DEFINE_OPCODE(OP, MNEMONIC, NAME) \
- case OP: { \
- const char *s = MNEMONIC; \
- return s ? s : #NAME; \
- }
-#include "FormatterBytecode.def"
-#undef DEFINE_SIGNATURE
- }
- return llvm::utostr(op);
-}
-
-std::string toString(FormatterBytecode::Selectors sel) {
- switch (sel) {
-#define DEFINE_SELECTOR(ID, NAME) \
- case ID: \
- return "@" #NAME;
-#include "FormatterBytecode.def"
-#undef DEFINE_SIGNATURE
- }
- return "@" + llvm::utostr(sel);
-}
-
-std::string toString(FormatterBytecode::Signatures sig) {
- switch (sig) {
-#define DEFINE_SIGNATURE(ID, NAME) \
- case ID: \
- return "@" #NAME;
-#include "FormatterBytecode.def"
-#undef DEFINE_SIGNATURE
- }
- return llvm::utostr(sig);
-}
-
-std::string toString(const FormatterBytecode::DataStack &data) {
- std::string s;
- llvm::raw_string_ostream os(s);
- os << "[ ";
- for (auto &d : data) {
- if (auto s = std::get_if<std::string>(&d))
- os << '"' << *s << '"';
- else if (auto u = std::get_if<uint64_t>(&d))
- os << *u << 'u';
- else if (auto i = std::get_if<int64_t>(&d))
- os << *i;
- else if (auto valobj = std::get_if<ValueObjectSP>(&d)) {
- if (!valobj->get())
- os << "null";
- else
- os << "object(" << valobj->get()->GetValueAsCString() << ')';
- } else if (auto type = std::get_if<CompilerType>(&d)) {
- os << '(' << type->GetTypeName(true) << ')';
- } else if (auto sel = std::get_if<FormatterBytecode::Selectors>(&d)) {
- os << toString(*sel);
- }
- os << ' ';
- }
- os << ']';
- return s;
-}
-
-namespace FormatterBytecode {
-
-/// Implement the @format function.
-static llvm::Error FormatImpl(DataStack &data) {
- auto fmt = data.Pop<std::string>();
- auto replacements =
- llvm::formatv_object_base::parseFormatString(fmt, 0, false);
- std::string s;
- llvm::raw_string_ostream os(s);
- unsigned num_args = 0;
- for (const auto &r : replacements)
- if (r.Type == llvm::ReplacementType::Format)
- num_args = std::max(num_args, r.Index + 1);
-
- if (data.size() < num_args)
- return llvm::createStringError("not enough arguments");
-
- for (const auto &r : replacements) {
- if (r.Type == llvm::ReplacementType::Literal) {
- os << r.Spec;
- continue;
- }
- using namespace llvm::support::detail;
- auto arg = data[data.size() - num_args + r.Index];
- auto format = [&](format_adapter &&adapter) {
- llvm::FmtAlign Align(adapter, r.Where, r.Width, r.Pad);
- Align.format(os, r.Options);
- };
-
- if (auto s = std::get_if<std::string>(&arg))
- format(build_format_adapter(s->c_str()));
- else if (auto u = std::get_if<uint64_t>(&arg))
- format(build_format_adapter(u));
- else if (auto i = std::get_if<int64_t>(&arg))
- format(build_format_adapter(i));
- else if (auto valobj = std::get_if<ValueObjectSP>(&arg)) {
- if (!valobj->get())
- format(build_format_adapter("null object"));
- else
- format(build_format_adapter(valobj->get()->GetValueAsCString()));
- } else if (auto type = std::get_if<CompilerType>(&arg))
- format(build_format_adapter(type->GetDisplayTypeName()));
- else if (auto sel = std::get_if<FormatterBytecode::Selectors>(&arg))
- format(build_format_adapter(toString(*sel)));
- }
- data.Push(s);
- return llvm::Error::success();
-}
-
-static llvm::Error TypeCheck(llvm::ArrayRef<DataStackElement> data,
- DataType type) {
- if (data.size() < 1)
- return llvm::createStringError("not enough elements on data stack");
-
- auto &elem = data.back();
- switch (type) {
- case Any:
- break;
- case String:
- if (!std::holds_alternative<std::string>(elem))
- return llvm::createStringError("expected String");
- break;
- case UInt:
- if (!std::holds_alternative<uint64_t>(elem))
- return llvm::createStringError("expected UInt");
- break;
- case Int:
- if (!std::holds_alternative<int64_t>(elem))
- return llvm::createStringError("expected Int");
- break;
- case Object:
- if (!std::holds_alternative<ValueObjectSP>(elem))
- return llvm::createStringError("expected Object");
- break;
- case Type:
- if (!std::holds_alternative<CompilerType>(elem))
- return llvm::createStringError("expected Type");
- break;
- case Selector:
- if (!std::holds_alternative<Selectors>(elem))
- return llvm::createStringError("expected Selector");
- break;
- }
- return llvm::Error::success();
-}
-
-static llvm::Error TypeCheck(llvm::ArrayRef<DataStackElement> data,
- DataType type1, DataType type2) {
- if (auto error = TypeCheck(data, type2))
- return error;
- return TypeCheck(data.drop_back(), type1);
-}
-
-static llvm::Error TypeCheck(llvm::ArrayRef<DataStackElement> data,
- DataType type1, DataType type2, DataType type3) {
- if (auto error = TypeCheck(data, type3))
- return error;
- return TypeCheck(data.drop_back(1), type2, type1);
-}
-
-llvm::Error Interpret(std::vector<ControlStackElement> &control,
- DataStack &data, Selectors sel) {
- if (control.empty())
- return llvm::Error::success();
- // Since the only data types are single endian and ULEBs, the
- // endianness should not matter.
- llvm::DataExtractor cur_block(control.back(), true, 64);
- llvm::DataExtractor::Cursor pc(0);
-
- while (!control.empty()) {
- /// Activate the top most block from the control stack.
- auto activate_block = [&]() {
- // Save the return address.
- if (control.size() > 1)
- control[control.size() - 2] = cur_block.getData().drop_front(pc.tell());
- cur_block = llvm::DataExtractor(control.back(), true, 64);
- if (pc)
- pc = llvm::DataExtractor::Cursor(0);
- };
-
- /// Fetch the next byte in the instruction stream.
- auto next_byte = [&]() -> uint8_t {
- // At the end of the current block?
- while (pc.tell() >= cur_block.size() && !control.empty()) {
- if (control.size() == 1) {
- control.pop_back();
- return 0;
- }
- control.pop_back();
- activate_block();
- }
-
- // Fetch the next instruction.
- return cur_block.getU8(pc);
- };
-
- // Fetch the next opcode.
- OpCodes opcode = (OpCodes)next_byte();
- if (control.empty() || !pc)
- return pc.takeError();
-
- LLDB_LOGV(GetLog(LLDBLog::DataFormatters),
- "[eval {0}] opcode={1}, control={2}, data={3}", toString(sel),
- toString(opcode), control.size(), toString(data));
-
- // Various shorthands to improve the readability of error handling.
-#define TYPE_CHECK(...) \
- if (auto error = TypeCheck(data, __VA_ARGS__)) \
- return error;
-
- auto error = [&](llvm::Twine msg) {
- return llvm::createStringError(msg + "(opcode=" + toString(opcode) + ")");
- };
-
- switch (opcode) {
- // Data stack manipulation.
- case op_dup:
- TYPE_CHECK(Any);
- data.Push(data.back());
- continue;
- case op_drop:
- TYPE_CHECK(Any);
- data.pop_back();
- continue;
- case op_pick: {
- TYPE_CHECK(UInt);
- uint64_t idx = data.Pop<uint64_t>();
- if (idx >= data.size())
- return error("index out of bounds");
- data.Push(data[idx]);
- continue;
- }
- case op_over:
- TYPE_CHECK(Any, Any);
- data.Push(data[data.size() - 2]);
- continue;
- case op_swap: {
- TYPE_CHECK(Any, Any);
- auto x = data.PopAny();
- auto y = data.PopAny();
- data.Push(x);
- data.Push(y);
- continue;
- }
- case op_rot: {
- TYPE_CHECK(Any, Any, Any);
- auto z = data.PopAny();
- auto y = data.PopAny();
- auto x = data.PopAny();
- data.Push(z);
- data.Push(x);
- data.Push(y);
- continue;
- }
-
- // Control stack manipulation.
- case op_begin: {
- uint64_t length = cur_block.getULEB128(pc);
- if (!pc)
- return pc.takeError();
- llvm::StringRef block = cur_block.getBytes(pc, length);
- if (!pc)
- return pc.takeError();
- control.push_back(block);
- continue;
- }
- case op_if:
- TYPE_CHECK(UInt);
- if (data.Pop<uint64_t>() != 0) {
- if (!cur_block.size())
- return error("empty control stack");
- activate_block();
- } else
- control.pop_back();
- continue;
- case op_ifelse:
- TYPE_CHECK(UInt);
- if (cur_block.size() < 2)
- return error("empty control stack");
- if (data.Pop<uint64_t>() == 0)
- control[control.size() - 2] = control.back();
- control.pop_back();
- activate_block();
- continue;
-
- // Literals.
- case op_lit_uint:
- data.Push(cur_block.getULEB128(pc));
- continue;
- case op_lit_int:
- data.Push(cur_block.getSLEB128(pc));
- continue;
- case op_lit_selector:
- data.Push(Selectors(cur_block.getU8(pc)));
- continue;
- case op_lit_string: {
- uint64_t length = cur_block.getULEB128(pc);
- llvm::StringRef bytes = cur_block.getBytes(pc, length);
- data.Push(bytes.str());
- continue;
- }
- case op_as_uint: {
- TYPE_CHECK(Int);
- uint64_t casted;
- int64_t val = data.Pop<int64_t>();
- memcpy(&casted, &val, sizeof(val));
- data.Push(casted);
- continue;
- }
- case op_as_int: {
- TYPE_CHECK(UInt);
- int64_t casted;
- uint64_t val = data.Pop<uint64_t>();
- memcpy(&casted, &val, sizeof(val));
- data.Push(casted);
- continue;
- }
- case op_is_null: {
- TYPE_CHECK(Object);
- data.Push(data.Pop<ValueObjectSP>() ? 0ULL : 1ULL);
- continue;
- }
-
- // Arithmetic, logic, etc.
-#define BINOP_IMPL(OP, CHECK_ZERO) \
- { \
- TYPE_CHECK(Any, Any); \
- auto y = data.PopAny(); \
- if (std::holds_alternative<uint64_t>(y)) { \
- if (CHECK_ZERO && !std::get<uint64_t>(y)) \
- return error(#OP " by zero"); \
- TYPE_CHECK(UInt); \
- data.Push((uint64_t)(data.Pop<uint64_t>() OP std::get<uint64_t>(y))); \
- } else if (std::holds_alternative<int64_t>(y)) { \
- if (CHECK_ZERO && !std::get<int64_t>(y)) \
- return error(#OP " by zero"); \
- TYPE_CHECK(Int); \
- data.Push((int64_t)(data.Pop<int64_t>() OP std::get<int64_t>(y))); \
- } else \
- return error("unsupported data types"); \
- }
-#define BINOP(OP) BINOP_IMPL(OP, false)
-#define BINOP_CHECKZERO(OP) BINOP_IMPL(OP, true)
- case op_plus:
- BINOP(+);
- continue;
- case op_minus:
- BINOP(-);
- continue;
- case op_mul:
- BINOP(*);
- continue;
- case op_div:
- BINOP_CHECKZERO(/);
- continue;
- case op_mod:
- BINOP_CHECKZERO(%);
- continue;
- case op_shl:
-#define SHIFTOP(OP) \
- { \
- TYPE_CHECK(Any, UInt); \
- uint64_t y = data.Pop<uint64_t>(); \
- if (y > 64) \
- return error("shift out of bounds"); \
- if (std::holds_alternative<uint64_t>(data.back())) { \
- uint64_t x = data.Pop<uint64_t>(); \
- data.Push(x OP y); \
- } else if (std::holds_alternative<int64_t>(data.back())) { \
- int64_t x = data.Pop<int64_t>(); \
- if (y > 64) \
- return error("shift out of bounds"); \
- if (y < 0) \
- return error("shift out of bounds"); \
- data.Push(x OP y); \
- } else \
- return error("unsupported data types"); \
- }
- SHIFTOP(<<);
- continue;
- case op_shr:
- SHIFTOP(<<);
- continue;
- case op_and:
- BINOP(&);
- continue;
- case op_or:
- BINOP(|);
- continue;
- case op_xor:
- BINOP(^);
- continue;
- case op_not:
- TYPE_CHECK(UInt);
- data.Push(~data.Pop<uint64_t>());
- continue;
- case op_eq:
- BINOP(==);
- continue;
- case op_neq:
- BINOP(!=);
- continue;
- case op_lt:
- BINOP(<);
- continue;
- case op_gt:
- BINOP(>);
- continue;
- case op_le:
- BINOP(<=);
- continue;
- case op_ge:
- BINOP(>=);
- continue;
- case op_call: {
- TYPE_CHECK(Selector);
- Selectors sel = data.Pop<Selectors>();
-
- // Shorthand to improve readability.
-#define POP_VALOBJ(VALOBJ) \
- auto VALOBJ = data.Pop<ValueObjectSP>(); \
- if (!VALOBJ) \
- return error("null object");
-
- auto sel_error = [&](const char *msg) {
- return llvm::createStringError("{0} (opcode={1}, selector={2})", msg,
- toString(opcode).c_str(),
- toString(sel).c_str());
- };
-
- switch (sel) {
- case sel_summary: {
- TYPE_CHECK(Object);
- POP_VALOBJ(valobj);
- const char *summary = valobj->GetSummaryAsCString();
- data.Push(summary ? std::string(valobj->GetSummaryAsCString())
- : std::string());
- break;
- }
- case sel_get_num_children: {
- TYPE_CHECK(Object);
- POP_VALOBJ(valobj);
- auto result = valobj->GetNumChildren();
- if (!result)
- return result.takeError();
- data.Push((uint64_t)*result);
- break;
- }
- case sel_get_child_at_index: {
- TYPE_CHECK(Object, UInt);
- auto index = data.Pop<uint64_t>();
- POP_VALOBJ(valobj);
- data.Push(valobj->GetChildAtIndex(index));
- break;
- }
- case sel_get_child_with_name: {
- TYPE_CHECK(Object, String);
- auto name = data.Pop<std::string>();
- POP_VALOBJ(valobj);
- data.Push(valobj->GetChildMemberWithName(name));
- break;
- }
- case sel_get_child_index: {
- TYPE_CHECK(Object, String);
- auto name = data.Pop<std::string>();
- POP_VALOBJ(valobj);
- data.Push((uint64_t)valobj->GetIndexOfChildWithName(name));
- break;
- }
- case sel_get_type: {
- TYPE_CHECK(Object);
- POP_VALOBJ(valobj);
- // FIXME: do we need to control dynamic type resolution?
- data.Push(valobj->GetTypeImpl().GetCompilerType(false));
- break;
- }
- case sel_get_template_argument_type: {
- TYPE_CHECK(Type, UInt);
- auto index = data.Pop<uint64_t>();
- auto type = data.Pop<CompilerType>();
- // FIXME: There is more code in SBType::GetTemplateArgumentType().
- data.Push(type.GetTypeTemplateArgument(index, true));
- break;
- }
- case sel_get_value: {
- TYPE_CHECK(Object);
- POP_VALOBJ(valobj);
- data.Push(std::string(valobj->GetValueAsCString()));
- break;
- }
- case sel_get_value_as_unsigned: {
- TYPE_CHECK(Object);
- POP_VALOBJ(valobj);
- bool success;
- uint64_t val = valobj->GetValueAsUnsigned(0, &success);
- data.Push(val);
- if (!success)
- return sel_error("failed to get value");
- break;
- }
- case sel_get_value_as_signed: {
- TYPE_CHECK(Object);
- POP_VALOBJ(valobj);
- bool success;
- int64_t val = valobj->GetValueAsSigned(0, &success);
- data.Push(val);
- if (!success)
- return sel_error("failed to get value");
- break;
- }
- case sel_get_value_as_address: {
- TYPE_CHECK(Object);
- POP_VALOBJ(valobj);
- bool success;
- uint64_t addr = valobj->GetValueAsUnsigned(0, &success);
- if (!success)
- return sel_error("failed to get value");
- if (auto process_sp = valobj->GetProcessSP())
- addr = process_sp->FixDataAddress(addr);
- data.Push(addr);
- break;
- }
- case sel_cast: {
- TYPE_CHECK(Object, Type);
- auto type = data.Pop<CompilerType>();
- POP_VALOBJ(valobj);
- data.Push(valobj->Cast(type));
- break;
- }
- case sel_strlen: {
- TYPE_CHECK(String);
- data.Push((uint64_t)data.Pop<std::string>().size());
- break;
- }
- case sel_fmt: {
- TYPE_CHECK(String);
- if (auto error = FormatImpl(data))
- return error;
- break;
- }
- default:
- return sel_error("selector not implemented");
- }
- continue;
- }
- }
- return error("opcode not implemented");
- }
- return pc.takeError();
-}
-} // namespace FormatterBytecode
-
-} // namespace lldb_private
diff --git a/lldb/source/DataFormatters/FormatterBytecode.def b/lldb/source/DataFormatters/FormatterBytecode.def
deleted file mode 100644
index c6645631fa0065..00000000000000
--- a/lldb/source/DataFormatters/FormatterBytecode.def
+++ /dev/null
@@ -1,101 +0,0 @@
-//===-- FormatterBytecode.def -----------------------------------*- 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 DEFINE_OPCODE
-#define DEFINE_OPCODE(OP, MNEMONIC, NAME)
-#endif
-#ifndef DEFINE_SELECTOR
-#define DEFINE_SELECTOR(ID, NAME)
-#endif
-#ifndef DEFINE_SIGNATURE
-#define DEFINE_SIGNATURE(ID, NAME)
-#endif
-
-// Opcodes.
-DEFINE_OPCODE(0x01, "dup", dup)
-DEFINE_OPCODE(0x02, "drop", drop)
-DEFINE_OPCODE(0x03, "pick", pick)
-DEFINE_OPCODE(0x04, "over", over)
-DEFINE_OPCODE(0x05, "swap", swap)
-DEFINE_OPCODE(0x06, "rot", rot)
-
-DEFINE_OPCODE(0x10, "{", begin)
-DEFINE_OPCODE(0x11, "if", if)
-DEFINE_OPCODE(0x12, "ifelse", ifelse)
-
-DEFINE_OPCODE(0x20, nullptr, lit_uint)
-DEFINE_OPCODE(0x21, nullptr, lit_int)
-DEFINE_OPCODE(0x22, nullptr, lit_string)
-DEFINE_OPCODE(0x23, nullptr, lit_selector)
-
-DEFINE_OPCODE(0x2a, "as_int", as_int)
-DEFINE_OPCODE(0x2b, "as_uint", as_uint)
-DEFINE_OPCODE(0x2c, "is_null", is_null)
-
-DEFINE_OPCODE(0x30, "+", plus)
-DEFINE_OPCODE(0x31, "-", minus)
-DEFINE_OPCODE(0x32, "*", mul)
-DEFINE_OPCODE(0x33, "/", div)
-DEFINE_OPCODE(0x34, "%", mod)
-DEFINE_OPCODE(0x35, "<<", shl)
-DEFINE_OPCODE(0x36, ">>", shr)
-
-DEFINE_OPCODE(0x40, "&", and)
-DEFINE_OPCODE(0x41, "|", or)
-DEFINE_OPCODE(0x42, "^", xor)
-DEFINE_OPCODE(0x43, "~", not)
-
-DEFINE_OPCODE(0x50, "=", eq)
-DEFINE_OPCODE(0x51, "!=", neq)
-DEFINE_OPCODE(0x52, "<", lt)
-DEFINE_OPCODE(0x53, ">", gt)
-DEFINE_OPCODE(0x54, "=<", le)
-DEFINE_OPCODE(0x55, ">=", ge)
-
-DEFINE_OPCODE(0x60, "call", call)
-
-// Selectors.
-DEFINE_SELECTOR(0x00, summary)
-DEFINE_SELECTOR(0x01, type_summary)
-
-DEFINE_SELECTOR(0x10, get_num_children)
-DEFINE_SELECTOR(0x11, get_child_at_index)
-DEFINE_SELECTOR(0x12, get_child_with_name)
-DEFINE_SELECTOR(0x13, get_child_index)
-DEFINE_SELECTOR(0x15, get_type)
-DEFINE_SELECTOR(0x16, get_template_argument_type)
-DEFINE_SELECTOR(0x17, cast)
-
-DEFINE_SELECTOR(0x20, get_value)
-DEFINE_SELECTOR(0x21, get_value_as_unsigned)
-DEFINE_SELECTOR(0x22, get_value_as_signed)
-DEFINE_SELECTOR(0x23, get_value_as_address)
-
-DEFINE_SELECTOR(0x40, read_memory_byte)
-DEFINE_SELECTOR(0x41, read_memory_uint32)
-DEFINE_SELECTOR(0x42, read_memory_int32)
-DEFINE_SELECTOR(0x43, read_memory_unsigned)
-DEFINE_SELECTOR(0x44, read_memory_signed)
-DEFINE_SELECTOR(0x45, read_memory_address)
-DEFINE_SELECTOR(0x46, read_memory)
-
-DEFINE_SELECTOR(0x50, fmt)
-DEFINE_SELECTOR(0x51, sprintf)
-DEFINE_SELECTOR(0x52, strlen)
-
-// Formatter signatures.
-DEFINE_SIGNATURE(0, summary)
-DEFINE_SIGNATURE(1, init)
-DEFINE_SIGNATURE(2, get_num_children)
-DEFINE_SIGNATURE(3, get_child_index)
-DEFINE_SIGNATURE(4, get_child_at_index)
-DEFINE_SIGNATURE(5, get_value)
-
-#undef DEFINE_OPCODE
-#undef DEFINE_SELECTOR
-#undef DEFINE_SIGNATURE
diff --git a/lldb/source/DataFormatters/FormatterBytecode.h b/lldb/source/DataFormatters/FormatterBytecode.h
deleted file mode 100644
index 21454d9c7e231f..00000000000000
--- a/lldb/source/DataFormatters/FormatterBytecode.h
+++ /dev/null
@@ -1,64 +0,0 @@
-//===-- FormatterBytecode.h -------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/DataFormatters/TypeSummary.h"
-#include "lldb/Symbol/CompilerType.h"
-
-namespace lldb_private {
-
-namespace FormatterBytecode {
-
-enum DataType : uint8_t { Any, String, Int, UInt, Object, Type, Selector };
-
-enum OpCodes : uint8_t {
-#define DEFINE_OPCODE(OP, MNEMONIC, NAME) op_##NAME = OP,
-#include "FormatterBytecode.def"
-#undef DEFINE_OPCODE
-};
-
-enum Selectors : uint8_t {
-#define DEFINE_SELECTOR(ID, NAME) sel_##NAME = ID,
-#include "FormatterBytecode.def"
-#undef DEFINE_SELECTOR
-};
-
-enum Signatures : uint8_t {
-#define DEFINE_SIGNATURE(ID, NAME) sig_##NAME = ID,
-#include "FormatterBytecode.def"
-#undef DEFINE_SIGNATURE
-};
-
-using ControlStackElement = llvm::StringRef;
-using DataStackElement =
- std::variant<std::string, uint64_t, int64_t, lldb::ValueObjectSP,
- CompilerType, Selectors>;
-struct DataStack : public std::vector<DataStackElement> {
- DataStack() = default;
- DataStack(lldb::ValueObjectSP initial_value)
- : std::vector<DataStackElement>({initial_value}) {}
- void Push(DataStackElement el) { push_back(el); }
- template <typename T> T Pop() {
- T el = std::get<T>(back());
- pop_back();
- return el;
- }
- DataStackElement PopAny() {
- DataStackElement el = back();
- pop_back();
- return el;
- }
-};
-llvm::Error Interpret(std::vector<ControlStackElement> &control,
- DataStack &data, Selectors sel);
-} // namespace FormatterBytecode
-
-std::string toString(FormatterBytecode::OpCodes op);
-std::string toString(FormatterBytecode::Selectors sel);
-std::string toString(FormatterBytecode::Signatures sig);
-
-} // namespace lldb_private
diff --git a/lldb/source/DataFormatters/FormatterSection.cpp b/lldb/source/DataFormatters/FormatterSection.cpp
deleted file mode 100644
index f70f41fdeb736f..00000000000000
--- a/lldb/source/DataFormatters/FormatterSection.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-//===-- FormatterBytecode.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 "FormatterBytecode.h"
-#include "lldb/Core/Module.h"
-#include "lldb/DataFormatters/DataVisualization.h"
-#include "lldb/Utility/LLDBLog.h"
-
-using namespace lldb;
-
-namespace lldb_private {
-static void ForEachFormatterInModule(
- Module &module, SectionType section_type,
- std::function<void(llvm::DataExtractor, llvm::StringRef)> fn) {
- auto *sections = module.GetSectionList();
- if (!sections)
- return;
-
- auto section_sp = sections->FindSectionByType(section_type, true);
- if (!section_sp)
- return;
-
- TypeCategoryImplSP category;
- DataVisualization::Categories::GetCategory(ConstString("default"), category);
-
- // The type summary record is serialized as follows.
- //
- // Each record contains, in order:
- // * Version number of the record format
- // * The remaining size of the record
- // * The size of the type identifier
- // * The type identifier, either a type name, or a regex
- // * The size of the entry
- // * The entry
- //
- // Integers are encoded using ULEB.
- //
- // Strings are encoded with first a length (ULEB), then the string contents,
- // and lastly a null terminator. The length includes the null.
-
- DataExtractor lldb_extractor;
- auto section_size = section_sp->GetSectionData(lldb_extractor);
- llvm::DataExtractor section = lldb_extractor.GetAsLLVM();
- bool le = section.isLittleEndian();
- uint8_t addr_size = section.getAddressSize();
- llvm::DataExtractor::Cursor cursor(0);
- while (cursor && cursor.tell() < section_size) {
- uint64_t version = section.getULEB128(cursor);
- uint64_t record_size = section.getULEB128(cursor);
- if (version == 1) {
- llvm::DataExtractor record(section.getData().drop_front(cursor.tell()),
- le, addr_size);
- llvm::DataExtractor::Cursor cursor(0);
- uint64_t type_size = record.getULEB128(cursor);
- llvm::StringRef type_name = record.getBytes(cursor, type_size);
- llvm::Error error = cursor.takeError();
- if (!error)
- fn(llvm::DataExtractor(record.getData().drop_front(cursor.tell()), le,
- addr_size),
- type_name);
- else
- LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), std::move(error),
- "{0}");
- } else {
- // Skip unsupported record.
- LLDB_LOG(
- GetLog(LLDBLog::DataFormatters),
- "Skipping unsupported embedded type summary of version {0} in {1}.",
- version, module.GetFileSpec());
- }
- section.skip(cursor, record_size);
- }
- if (!cursor)
- LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(), "{0}");
-}
-
-void LoadTypeSummariesForModule(ModuleSP module_sp) {
- ForEachFormatterInModule(
- *module_sp, eSectionTypeLLDBTypeSummaries,
- [&](llvm::DataExtractor extractor, llvm::StringRef type_name) {
- TypeCategoryImplSP category;
- DataVisualization::Categories::GetCategory(ConstString("default"),
- category);
- // The type summary record is serialized as follows.
- //
- // * The size of the summary string
- // * The summary string
- //
- // Integers are encoded using ULEB.
- llvm::DataExtractor::Cursor cursor(0);
- uint64_t summary_size = extractor.getULEB128(cursor);
- llvm::StringRef summary_string =
- extractor.getBytes(cursor, summary_size);
- if (!cursor) {
- LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(),
- "{0}");
- return;
- }
- if (type_name.empty() || summary_string.empty()) {
- LLDB_LOG(GetLog(LLDBLog::DataFormatters),
- "Missing string(s) in embedded type summary in {0}, "
- "type_name={1}, summary={2}",
- module_sp->GetFileSpec(), type_name, summary_string);
- return;
- }
- TypeSummaryImpl::Flags flags;
- auto summary_sp = std::make_shared<StringSummaryFormat>(
- flags, summary_string.str().c_str());
- FormatterMatchType match_type = eFormatterMatchExact;
- if (type_name.front() == '^')
- match_type = eFormatterMatchRegex;
- category->AddTypeSummary(type_name, match_type, summary_sp);
- LLDB_LOG(GetLog(LLDBLog::DataFormatters),
- "Loaded embedded type summary for '{0}' from {1}.", type_name,
- module_sp->GetFileSpec());
- });
-}
-
-void LoadFormattersForModule(ModuleSP module_sp) {
- ForEachFormatterInModule(
- *module_sp, eSectionTypeLLDBFormatters,
- [&](llvm::DataExtractor extractor, llvm::StringRef type_name) {
- // * Function signature (1 byte)
- // * Length of the program (ULEB128)
- // * The program bytecode
- TypeCategoryImplSP category;
- DataVisualization::Categories::GetCategory(ConstString("default"),
- category);
- llvm::DataExtractor::Cursor cursor(0);
- uint64_t flags = extractor.getULEB128(cursor);
- while (cursor && cursor.tell() < extractor.size()) {
- uint8_t signature = extractor.getU8(cursor);
- uint64_t size = extractor.getULEB128(cursor);
- llvm::StringRef bytecode = extractor.getBytes(cursor, size);
- if (!cursor) {
- LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(),
- "{0}");
- return;
- }
- if (signature == 0) {
- auto summary_sp = std::make_shared<BytecodeSummaryFormat>(
- TypeSummaryImpl::Flags(flags),
- llvm::MemoryBuffer::getMemBufferCopy(bytecode));
- FormatterMatchType match_type = eFormatterMatchExact;
- if (type_name.front() == '^')
- match_type = eFormatterMatchRegex;
- category->AddTypeSummary(type_name, match_type, summary_sp);
- LLDB_LOG(GetLog(LLDBLog::DataFormatters),
- "Loaded embedded type summary for '{0}' from {1}.",
- type_name, module_sp->GetFileSpec());
- } else
- LLDB_LOG(GetLog(LLDBLog::DataFormatters),
- "Unsupported formatter signature {0} for '{1}' in {2}",
- signature, type_name, module_sp->GetFileSpec());
- }
- });
-}
-} // namespace lldb_private
diff --git a/lldb/source/DataFormatters/TypeSummary.cpp b/lldb/source/DataFormatters/TypeSummary.cpp
index 2c863b364538f3..3538c1b60c8e9e 100644
--- a/lldb/source/DataFormatters/TypeSummary.cpp
+++ b/lldb/source/DataFormatters/TypeSummary.cpp
@@ -8,7 +8,9 @@
#include "lldb/DataFormatters/TypeSummary.h"
-#include "FormatterBytecode.h"
+
+
+
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-public.h"
@@ -56,8 +58,6 @@ std::string TypeSummaryImpl::GetSummaryKindName() {
return "python";
case Kind::eInternal:
return "c++";
- case Kind::eBytecode:
- return "bytecode";
}
}
@@ -230,74 +230,3 @@ std::string ScriptSummaryFormat::GetDescription() {
}
std::string ScriptSummaryFormat::GetName() { return m_script_formatter_name; }
-
-BytecodeSummaryFormat::BytecodeSummaryFormat(
- const TypeSummaryImpl::Flags &flags,
- std::unique_ptr<llvm::MemoryBuffer> bytecode)
- : TypeSummaryImpl(Kind::eBytecode, flags), m_bytecode(std::move(bytecode)) {
-}
-
-bool BytecodeSummaryFormat::FormatObject(ValueObject *valobj,
- std::string &retval,
- const TypeSummaryOptions &options) {
- if (!valobj)
- return false;
-
- TargetSP target_sp(valobj->GetTargetSP());
-
- if (!target_sp) {
- retval.assign("error: no target");
- return false;
- }
-
- std::vector<FormatterBytecode::ControlStackElement> control(
- {m_bytecode->getBuffer()});
- FormatterBytecode::DataStack data({valobj->GetSP()});
- llvm::Error error = FormatterBytecode::Interpret(
- control, data, FormatterBytecode::sel_summary);
- if (error) {
- retval = llvm::toString(std::move(error));
- return false;
- }
- if (!data.size()) {
- retval = "empty stack";
- return false;
- }
- auto &top = data.back();
- retval = "";
- llvm::raw_string_ostream os(retval);
- if (auto s = std::get_if<std::string>(&top))
- os << *s;
- else if (auto u = std::get_if<uint64_t>(&top))
- os << *u;
- else if (auto i = std::get_if<int64_t>(&top))
- os << *i;
- else if (auto valobj = std::get_if<ValueObjectSP>(&top)) {
- if (!valobj->get())
- os << "empty object";
- else
- os << valobj->get()->GetValueAsCString();
- } else if (auto type = std::get_if<CompilerType>(&top)) {
- os << type->TypeDescription();
- } else if (auto sel = std::get_if<FormatterBytecode::Selectors>(&top)) {
- os << toString(*sel);
- }
- return true;
-}
-
-std::string BytecodeSummaryFormat::GetDescription() {
- StreamString sstr;
- sstr.Printf("%s%s%s%s%s%s%s\n ", Cascades() ? "" : " (not cascading)",
- !DoesPrintChildren(nullptr) ? "" : " (show children)",
- !DoesPrintValue(nullptr) ? " (hide value)" : "",
- IsOneLiner() ? " (one-line printout)" : "",
- SkipsPointers() ? " (skip pointers)" : "",
- SkipsReferences() ? " (skip references)" : "",
- HideNames(nullptr) ? " (hide member names)" : "");
- // FIXME: sstr.PutCString(disassembly);
- return std::string(sstr.GetString());
-}
-
-std::string BytecodeSummaryFormat::GetName() {
- return "LLDB bytecode formatter";
-}
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index b16cb114bec88e..a8249cf103833e 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -1697,7 +1697,6 @@ static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
.Case(".gosymtab", eSectionTypeGoSymtab)
.Case(".text", eSectionTypeCode)
.Case(".lldbsummaries", lldb::eSectionTypeLLDBTypeSummaries)
- .Case(".lldbformatters", lldb::eSectionTypeLLDBFormatters)
.Case(".swift_ast", eSectionTypeSwiftModules)
.Default(eSectionTypeOther);
}
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 488c9bd1e54af1..7e17fd8c53cd01 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -1210,7 +1210,6 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
case eSectionTypeDWARFGNUDebugAltLink:
case eSectionTypeCTF:
case eSectionTypeLLDBTypeSummaries:
- case eSectionTypeLLDBFormatters:
case eSectionTypeSwiftModules:
return AddressClass::eDebug;
@@ -1487,7 +1486,6 @@ static lldb::SectionType GetSectionType(uint32_t flags,
static ConstString g_sect_name_go_symtab("__gosymtab");
static ConstString g_sect_name_ctf("__ctf");
static ConstString g_sect_name_lldb_summaries("__lldbsummaries");
- static ConstString g_sect_name_lldb_formatters("__lldbformatters");
static ConstString g_sect_name_swift_ast("__swift_ast");
if (section_name == g_sect_name_dwarf_debug_abbrev)
@@ -1570,8 +1568,6 @@ static lldb::SectionType GetSectionType(uint32_t flags,
return eSectionTypeCTF;
if (section_name == g_sect_name_lldb_summaries)
return lldb::eSectionTypeLLDBTypeSummaries;
- if (section_name == g_sect_name_lldb_formatters)
- return lldb::eSectionTypeLLDBFormatters;
if (section_name == g_sect_name_swift_ast)
return eSectionTypeSwiftModules;
if (section_name == g_sect_name_objc_data ||
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index bfdb8140e40aff..bb712da7f6d67d 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -1011,7 +1011,6 @@ SectionType ObjectFilePECOFF::GetSectionType(llvm::StringRef sect_name,
.Cases(".eh_frame", ".eh_fram", eSectionTypeEHFrame)
.Case(".gosymtab", eSectionTypeGoSymtab)
.Case(".lldbsummaries", lldb::eSectionTypeLLDBTypeSummaries)
- .Case(".lldbformatters", lldb::eSectionTypeLLDBFormatters)
.Case("swiftast", eSectionTypeSwiftModules)
.Default(eSectionTypeInvalid);
if (section_type != eSectionTypeInvalid)
diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp
index d3881f8ccf7fe8..3100e6b813b631 100644
--- a/lldb/source/Symbol/ObjectFile.cpp
+++ b/lldb/source/Symbol/ObjectFile.cpp
@@ -366,7 +366,6 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) {
case eSectionTypeDWARFAppleObjC:
case eSectionTypeDWARFGNUDebugAltLink:
case eSectionTypeCTF:
- case eSectionTypeLLDBFormatters:
case eSectionTypeLLDBTypeSummaries:
case eSectionTypeSwiftModules:
return AddressClass::eDebug;
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 46216ba2d566d7..9ac85ad3ed5ee6 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -24,7 +24,9 @@
#include "lldb/Core/Section.h"
#include "lldb/Core/SourceManager.h"
#include "lldb/Core/StructuredDataImpl.h"
-#include "lldb/DataFormatters/FormatterSection.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Expression/REPL.h"
@@ -64,6 +66,8 @@
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
+#include "lldb/ValueObject/ValueObject.h"
+#include "lldb/ValueObject/ValueObjectConstResult.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SetVector.h"
@@ -1537,6 +1541,76 @@ static void LoadScriptingResourceForModule(const ModuleSP &module_sp,
feedback_stream.GetData());
}
+// Load type summaries embedded in the binary. These are type summaries provided
+// by the authors of the code.
+static void LoadTypeSummariesForModule(ModuleSP module_sp) {
+ auto *sections = module_sp->GetSectionList();
+ if (!sections)
+ return;
+
+ auto summaries_sp =
+ sections->FindSectionByType(eSectionTypeLLDBTypeSummaries, true);
+ if (!summaries_sp)
+ return;
+
+ Log *log = GetLog(LLDBLog::DataFormatters);
+ const char *module_name = module_sp->GetObjectName().GetCString();
+
+ TypeCategoryImplSP category;
+ DataVisualization::Categories::GetCategory(ConstString("default"), category);
+
+ // The type summary record is serialized as follows.
+ //
+ // Each record contains, in order:
+ // * Version number of the record format
+ // * The remaining size of the record
+ // * The size of the type identifier
+ // * The type identifier, either a type name, or a regex
+ // * The size of the summary string
+ // * The summary string
+ //
+ // Integers are encoded using ULEB.
+ //
+ // Strings are encoded with first a length (ULEB), then the string contents,
+ // and lastly a null terminator. The length includes the null.
+
+ DataExtractor extractor;
+ auto section_size = summaries_sp->GetSectionData(extractor);
+ lldb::offset_t offset = 0;
+ while (offset < section_size) {
+ uint64_t version = extractor.GetULEB128(&offset);
+ uint64_t record_size = extractor.GetULEB128(&offset);
+ if (version == 1) {
+ uint64_t type_size = extractor.GetULEB128(&offset);
+ llvm::StringRef type_name = extractor.GetCStr(&offset, type_size);
+ uint64_t summary_size = extractor.GetULEB128(&offset);
+ llvm::StringRef summary_string = extractor.GetCStr(&offset, summary_size);
+ if (!type_name.empty() && !summary_string.empty()) {
+ TypeSummaryImpl::Flags flags;
+ auto summary_sp =
+ std::make_shared<StringSummaryFormat>(flags, summary_string.data());
+ FormatterMatchType match_type = eFormatterMatchExact;
+ if (summary_string.front() == '^' && summary_string.back() == '$')
+ match_type = eFormatterMatchRegex;
+ category->AddTypeSummary(type_name, match_type, summary_sp);
+ LLDB_LOGF(log, "Loaded embedded type summary for '%s' from %s.",
+ type_name.data(), module_name);
+ } else {
+ if (type_name.empty())
+ LLDB_LOGF(log, "Missing string(s) in embedded type summary in %s.",
+ module_name);
+ }
+ } else {
+ // Skip unsupported record.
+ offset += record_size;
+ LLDB_LOGF(
+ log,
+ "Skipping unsupported embedded type summary of version %llu in %s.",
+ version, module_name);
+ }
+ }
+}
+
void Target::ClearModules(bool delete_locations) {
ModulesDidUnload(m_images, delete_locations);
m_section_load_history.Clear();
@@ -1818,7 +1892,6 @@ void Target::ModulesDidLoad(ModuleList &module_list) {
ModuleSP module_sp(module_list.GetModuleAtIndex(idx));
LoadScriptingResourceForModule(module_sp, this);
LoadTypeSummariesForModule(module_sp);
- LoadFormattersForModule(module_sp);
}
m_breakpoint_list.UpdateBreakpoints(module_list, true, false);
m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false);
diff --git a/lldb/test/API/functionalities/data-formatter/bytecode-summary/Makefile b/lldb/test/API/functionalities/data-formatter/bytecode-summary/Makefile
deleted file mode 100644
index c9319d6e6888a4..00000000000000
--- a/lldb/test/API/functionalities/data-formatter/bytecode-summary/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-C_SOURCES := main.c
-include Makefile.rules
diff --git a/lldb/test/API/functionalities/data-formatter/bytecode-summary/TestBytecodeSummary.py b/lldb/test/API/functionalities/data-formatter/bytecode-summary/TestBytecodeSummary.py
deleted file mode 100644
index 2b27bd3cdcda71..00000000000000
--- a/lldb/test/API/functionalities/data-formatter/bytecode-summary/TestBytecodeSummary.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import lldb
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-
-
-class TestCase(TestBase):
- @skipUnlessDarwin
- def test(self):
- self.build()
- if self.TraceOn():
- self.expect("log enable -v lldb formatters")
- lldbutil.run_to_source_breakpoint(
- self, "break here", lldb.SBFileSpec("main.cpp")
- )
- self.expect("v x", substrs=["(MyOptional<int>) x = None"])
- self.expect("v y", substrs=["(MyOptional<int>) y = 42"])
diff --git a/lldb/test/API/functionalities/data-formatter/bytecode-summary/main.cpp b/lldb/test/API/functionalities/data-formatter/bytecode-summary/main.cpp
deleted file mode 100644
index 35406acd6d0c4e..00000000000000
--- a/lldb/test/API/functionalities/data-formatter/bytecode-summary/main.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-// A bare-bones llvm::Optional reimplementation.
-
-template <typename T> struct MyOptionalStorage {
- MyOptionalStorage(T val) : value(val), hasVal(true) {}
- MyOptionalStorage() {}
- T value;
- bool hasVal = false;
-};
-
-template <typename T> struct MyOptional {
- MyOptionalStorage<T> Storage;
- MyOptional(T val) : Storage(val) {}
- MyOptional() {}
- T &operator*() { return Storage.value; }
-};
-
-void stop() {}
-
-int main(int argc, char **argv) {
- MyOptional<int> x, y = 42;
- stop(); // break here
- return *y;
-}
-
-// Produced from the assembler in
-// Shell/ScriptInterpreter/Python/Inputs/FormatterBytecode/formatter.py
-__attribute__((used, section("__DATA_CONST,__lldbformatters"))) unsigned char
- _MyOptional_type_summary[] =
- "\x01" // version
- "\xa4" // record size
- "\x01" // record size
- "\x10" // type name size
- "^MyOptional<.+>$" // type name
- "\x00" // flags
- "\x00" // sig_summary
- "\x8d" // program size
- "\x01" // program size
- "\x1\x22\x7Storage#\x12\x60\x1,C\x10\x1\x5\x11\x2\x1\x22\x6hasVal#"
- "\x12\x60\x1,\x10\x1e\x2\x22\x1b<could not read MyOptional>\x10G#!\x60 "
- "\x0P\x10\x6\x22\x4None\x10\x36\x1#\x15\x60 "
- "\x0#\x16\x60\x5\x22\x5value#\x12\x60\x5#\x17\x60\x1,"
- "\x10\x6\x22\x4None\x10\x11\x1#\x0\x60\x1#R\x60\x10\x3# "
- "\x60\x10\x1\x2\x12\x12\x12\x12"; // summary function
diff --git a/lldb/unittests/DataFormatter/CMakeLists.txt b/lldb/unittests/DataFormatter/CMakeLists.txt
index b858db1c716347..9d967a72bfd1fa 100644
--- a/lldb/unittests/DataFormatter/CMakeLists.txt
+++ b/lldb/unittests/DataFormatter/CMakeLists.txt
@@ -1,7 +1,6 @@
add_lldb_unittest(LLDBFormatterTests
FormatManagerTests.cpp
FormattersContainerTest.cpp
- FormatterBytecodeTest.cpp
StringPrinterTests.cpp
LINK_LIBS
diff --git a/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp b/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp
deleted file mode 100644
index 15d9229de00332..00000000000000
--- a/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-#include "DataFormatters/FormatterBytecode.h"
-#include "lldb/Utility/StreamString.h"
-
-#include "gtest/gtest.h"
-
-using namespace lldb_private;
-using namespace lldb;
-using namespace FormatterBytecode;
-using llvm::StringRef;
-
-namespace {
-class FormatterBytecodeTest : public ::testing::Test {};
-
-bool Interpret(std::vector<uint8_t> code, DataStack &data) {
- auto buf =
- StringRef(reinterpret_cast<const char *>(code.data()), code.size());
- std::vector<ControlStackElement> control({buf});
- if (auto error = Interpret(control, data, sel_summary)) {
-#ifndef NDEBUG
- llvm::errs() << llvm::toString(std::move(error)) << '\n';
-#else
- llvm::consumeError(std::move(error));
-#endif
- return false;
- }
- return true;
-}
-
-} // namespace
-
-TEST_F(FormatterBytecodeTest, StackOps) {
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 23, op_dup, op_plus}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 46u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_drop}, data));
- ASSERT_EQ(data.size(), 0u);
- }
- {
- for (unsigned char i = 0; i < 3; ++i) {
- DataStack data;
-
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_lit_uint, 2,
- op_lit_uint, i, op_pick},
- data));
- ASSERT_EQ(data.Pop<uint64_t>(), i);
- }
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_over}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_swap}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret(
- {op_lit_uint, 0, op_lit_uint, 1, op_lit_uint, 2, op_rot}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- ASSERT_EQ(data.Pop<uint64_t>(), 2u);
- }
-}
-
-TEST_F(FormatterBytecodeTest, ControlOps) {
- {
- DataStack data;
- ASSERT_TRUE(
- Interpret({op_lit_uint, 0, op_begin, 2, op_lit_uint, 42, op_if}, data));
- ASSERT_EQ(data.size(), 0u);
- }
- {
- DataStack data;
- ASSERT_TRUE(
- Interpret({op_lit_uint, 1, op_begin, 2, op_lit_uint, 42, op_if}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 42u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_begin, 2, op_lit_uint, 42,
- op_begin, 2, op_lit_uint, 23, op_ifelse},
- data));
- ASSERT_EQ(data.Pop<uint64_t>(), 23u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_begin, 2, op_lit_uint, 42,
- op_begin, 2, op_lit_uint, 23, op_ifelse},
- data));
- ASSERT_EQ(data.Pop<uint64_t>(), 42u);
- }
- {
- DataStack data(lldb::ValueObjectSP{});
- ASSERT_TRUE(Interpret({op_is_null}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 1u, op_as_int}, data));
- ASSERT_EQ(data.Pop<int64_t>(), 1);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_int, 126, op_as_uint}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), ~1ULL);
- }
-}
-
-TEST_F(FormatterBytecodeTest, ArithOps) {
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 2, op_lit_uint, 3, op_plus}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 5u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 3, op_lit_uint, 2, op_minus}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 3, op_lit_uint, 2, op_mul}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 6u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 6, op_lit_uint, 2, op_div}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 3u);
- }
- {
- DataStack data;
- ASSERT_FALSE(Interpret({op_lit_uint, 23, op_lit_uint, 0, op_div}, data));
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 2, op_shl}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 4u);
- }
- {
- DataStack data;
- unsigned char minus_one = 127;
- ASSERT_TRUE(
- Interpret({op_lit_int, minus_one, op_lit_uint, 2, op_shl}, data));
- ASSERT_EQ(data.Pop<int64_t>(), -4);
- }
- {
- DataStack data;
- ASSERT_FALSE(Interpret({op_lit_uint, 1, op_lit_uint, 65, op_shl}, data));
- ASSERT_FALSE(Interpret({op_lit_uint, 1, op_lit_uint, 65, op_shr}, data));
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_and}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_and}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_or}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_or}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_or}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_xor}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_xor}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_xor}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_not}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0xffffffffffffffff);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_eq}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_eq}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_neq}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_neq}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_lt}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_lt}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_lt}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_gt}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_gt}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_gt}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_le}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_le}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_le}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- }
- {
- DataStack data;
- ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_ge}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 0u);
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_ge}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_ge}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 1u);
- }
-}
-
-TEST_F(FormatterBytecodeTest, CallOps) {
- {
- DataStack data;
- data.Push(std::string{"hello"});
- ASSERT_TRUE(Interpret({op_lit_selector, sel_strlen, op_call}, data));
- ASSERT_EQ(data.Pop<uint64_t>(), 5u);
- }
- {
- DataStack data;
- data.Push(std::string{"A"});
- data.Push(std::string{"B"});
- data.Push(std::string{"{1}{0}"});
- ASSERT_TRUE(Interpret({op_lit_selector, sel_fmt, op_call}, data));
- ASSERT_EQ(data.Pop<std::string>(), "BA");
- }
- {
- DataStack data;
- data.Push(std::string{"{0}"});
- ASSERT_FALSE(Interpret({op_lit_selector, sel_fmt, op_call}, data));
- }
-}
More information about the lldb-commits
mailing list