summaryrefslogtreecommitdiff
path: root/tools/lldb-test
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:06:29 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:06:29 +0000
commit94994d372d014ce4c8758b9605d63fae651bd8aa (patch)
tree51c0b708bd59f205d6b35cb2a8c24d62f0c33d77 /tools/lldb-test
parent39be7ce23363d12ae3e49aeb1fdb2bfeb892e836 (diff)
Notes
Diffstat (limited to 'tools/lldb-test')
-rw-r--r--tools/lldb-test/FormatUtil.cpp47
-rw-r--r--tools/lldb-test/FormatUtil.h27
-rw-r--r--tools/lldb-test/SystemInitializerTest.cpp40
-rw-r--r--tools/lldb-test/SystemInitializerTest.h2
-rw-r--r--tools/lldb-test/lldb-test.cpp290
5 files changed, 261 insertions, 145 deletions
diff --git a/tools/lldb-test/FormatUtil.cpp b/tools/lldb-test/FormatUtil.cpp
index 381cbd6e25b8..970f25a6b42f 100644
--- a/tools/lldb-test/FormatUtil.cpp
+++ b/tools/lldb-test/FormatUtil.cpp
@@ -14,6 +14,11 @@
using namespace lldb_private;
using namespace llvm;
+LinePrinter::Line::~Line() {
+ if (P)
+ P->NewLine();
+}
+
LinePrinter::LinePrinter(int Indent, llvm::raw_ostream &Stream)
: OS(Stream), IndentSpaces(Indent), CurrentIndent(0) {}
@@ -31,39 +36,31 @@ void LinePrinter::Unindent(uint32_t Amount) {
void LinePrinter::NewLine() {
OS << "\n";
- OS.indent(CurrentIndent);
-}
-
-void LinePrinter::print(const Twine &T) { OS << T; }
-
-void LinePrinter::printLine(const Twine &T) {
- NewLine();
- OS << T;
}
void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
uint32_t StartOffset) {
- NewLine();
- OS << Label << " (";
- if (!Data.empty()) {
- OS << "\n";
- OS << format_bytes_with_ascii(Data, StartOffset, 32, 4,
- CurrentIndent + IndentSpaces, true);
- NewLine();
+ if (Data.empty()) {
+ line() << Label << " ()";
+ return;
}
- OS << ")";
+ line() << Label << " (";
+ OS << format_bytes_with_ascii(Data, StartOffset, 32, 4,
+ CurrentIndent + IndentSpaces, true);
+ NewLine();
+ line() << ")";
}
void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
uint64_t Base, uint32_t StartOffset) {
- NewLine();
- OS << Label << " (";
- if (!Data.empty()) {
- OS << "\n";
- Base += StartOffset;
- OS << format_bytes_with_ascii(Data, Base, 32, 4,
- CurrentIndent + IndentSpaces, true);
- NewLine();
+ if (Data.empty()) {
+ line() << Label << " ()";
+ return;
}
- OS << ")";
+ line() << Label << " (";
+ Base += StartOffset;
+ OS << format_bytes_with_ascii(Data, Base, 32, 4, CurrentIndent + IndentSpaces,
+ true);
+ NewLine();
+ line() << ")";
}
diff --git a/tools/lldb-test/FormatUtil.h b/tools/lldb-test/FormatUtil.h
index f22ee41662ee..598d4c5440f5 100644
--- a/tools/lldb-test/FormatUtil.h
+++ b/tools/lldb-test/FormatUtil.h
@@ -26,27 +26,36 @@ class LinePrinter {
int CurrentIndent;
public:
+ class Line {
+ LinePrinter *P;
+
+ public:
+ Line(LinePrinter &P) : P(&P) { P.OS.indent(P.CurrentIndent); }
+ ~Line();
+
+ Line(Line &&RHS) : P(RHS.P) { RHS.P = nullptr; }
+ void operator=(Line &&) = delete;
+
+ operator llvm::raw_ostream &() { return P->OS; }
+ };
+
LinePrinter(int Indent, llvm::raw_ostream &Stream);
void Indent(uint32_t Amount = 0);
void Unindent(uint32_t Amount = 0);
void NewLine();
- void printLine(const llvm::Twine &T);
- void print(const llvm::Twine &T);
+ void printLine(const llvm::Twine &T) { line() << T; }
template <typename... Ts> void formatLine(const char *Fmt, Ts &&... Items) {
printLine(llvm::formatv(Fmt, std::forward<Ts>(Items)...));
}
- template <typename... Ts> void format(const char *Fmt, Ts &&... Items) {
- print(llvm::formatv(Fmt, std::forward<Ts>(Items)...));
- }
void formatBinary(llvm::StringRef Label, llvm::ArrayRef<uint8_t> Data,
uint32_t StartOffset);
void formatBinary(llvm::StringRef Label, llvm::ArrayRef<uint8_t> Data,
uint64_t BaseAddr, uint32_t StartOffset);
- llvm::raw_ostream &getStream() { return OS; }
+ Line line() { return Line(*this); }
int getIndentLevel() const { return CurrentIndent; }
};
@@ -64,12 +73,6 @@ struct AutoIndent {
uint32_t Amount = 0;
};
-template <class T>
-inline llvm::raw_ostream &operator<<(LinePrinter &Printer, const T &Item) {
- Printer.getStream() << Item;
- return Printer.getStream();
-}
-
} // namespace lldb_private
#endif
diff --git a/tools/lldb-test/SystemInitializerTest.cpp b/tools/lldb-test/SystemInitializerTest.cpp
index 2c190ecfc745..1220312def84 100644
--- a/tools/lldb-test/SystemInitializerTest.cpp
+++ b/tools/lldb-test/SystemInitializerTest.cpp
@@ -14,9 +14,6 @@
#include "lldb/Initialization/SystemInitializerCommon.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/GoASTContext.h"
-#include "lldb/Symbol/JavaASTContext.h"
-#include "lldb/Symbol/OCamlASTContext.h"
#include "lldb/Utility/Timer.h"
#include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h"
@@ -48,22 +45,17 @@
#include "Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.h"
#include "Plugins/JITLoader/GDB/JITLoaderGDB.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
-#include "Plugins/Language/Go/GoLanguage.h"
-#include "Plugins/Language/Java/JavaLanguage.h"
-#include "Plugins/Language/OCaml/OCamlLanguage.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h"
#include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h"
-#include "Plugins/LanguageRuntime/Go/GoLanguageRuntime.h"
-#include "Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h"
#include "Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h"
#include "Plugins/MemoryHistory/asan/MemoryHistoryASan.h"
+#include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h"
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
-#include "Plugins/OperatingSystem/Go/OperatingSystemGo.h"
#include "Plugins/Platform/Android/PlatformAndroid.h"
#include "Plugins/Platform/FreeBSD/PlatformFreeBSD.h"
#include "Plugins/Platform/Kalimba/PlatformKalimba.h"
@@ -78,6 +70,7 @@
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Plugins/Process/minidump/ProcessMinidump.h"
#include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h"
+#include "Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h"
#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
@@ -120,16 +113,18 @@ SystemInitializerTest::SystemInitializerTest() {}
SystemInitializerTest::~SystemInitializerTest() {}
-void SystemInitializerTest::Initialize() {
- SystemInitializerCommon::Initialize();
+llvm::Error
+SystemInitializerTest::Initialize(const InitializerOptions &options) {
+ if (auto e = SystemInitializerCommon::Initialize(options))
+ return e;
+ breakpad::ObjectFileBreakpad::Initialize();
ObjectFileELF::Initialize();
ObjectFileMachO::Initialize();
ObjectFilePECOFF::Initialize();
ScriptInterpreterNone::Initialize();
- OperatingSystemGo::Initialize();
platform_freebsd::PlatformFreeBSD::Initialize();
platform_linux::PlatformLinux::Initialize();
@@ -152,9 +147,6 @@ void SystemInitializerTest::Initialize() {
llvm::InitializeAllDisassemblers();
ClangASTContext::Initialize();
- GoASTContext::Initialize();
- JavaASTContext::Initialize();
- OCamlASTContext::Initialize();
ABIMacOSX_i386::Initialize();
ABIMacOSX_arm::Initialize();
@@ -185,6 +177,7 @@ void SystemInitializerTest::Initialize() {
MainThreadCheckerRuntime::Initialize();
SymbolVendorELF::Initialize();
+ breakpad::SymbolFileBreakpad::Initialize();
SymbolFileDWARF::Initialize();
SymbolFilePDB::Initialize();
SymbolFileSymtab::Initialize();
@@ -198,15 +191,10 @@ void SystemInitializerTest::Initialize() {
AppleObjCRuntimeV1::Initialize();
SystemRuntimeMacOSX::Initialize();
RenderScriptRuntime::Initialize();
- GoLanguageRuntime::Initialize();
- JavaLanguageRuntime::Initialize();
CPlusPlusLanguage::Initialize();
- GoLanguage::Initialize();
- JavaLanguage::Initialize();
ObjCLanguage::Initialize();
ObjCPlusPlusLanguage::Initialize();
- OCamlLanguage::Initialize();
#if defined(_WIN32)
ProcessWindows::Initialize();
@@ -249,6 +237,8 @@ void SystemInitializerTest::Initialize() {
// AFTER PluginManager::Initialize is called.
Debugger::SettingsInitialize();
+
+ return llvm::Error::success();
}
void SystemInitializerTest::Terminate() {
@@ -261,9 +251,6 @@ void SystemInitializerTest::Terminate() {
PluginManager::Terminate();
ClangASTContext::Terminate();
- GoASTContext::Terminate();
- JavaASTContext::Terminate();
- OCamlASTContext::Terminate();
ABIMacOSX_i386::Terminate();
ABIMacOSX_arm::Terminate();
@@ -289,6 +276,7 @@ void SystemInitializerTest::Terminate() {
UndefinedBehaviorSanitizerRuntime::Terminate();
MainThreadCheckerRuntime::Terminate();
SymbolVendorELF::Terminate();
+ breakpad::SymbolFileBreakpad::Terminate();
SymbolFileDWARF::Terminate();
SymbolFilePDB::Terminate();
SymbolFileSymtab::Terminate();
@@ -302,14 +290,10 @@ void SystemInitializerTest::Terminate() {
AppleObjCRuntimeV1::Terminate();
SystemRuntimeMacOSX::Terminate();
RenderScriptRuntime::Terminate();
- JavaLanguageRuntime::Terminate();
CPlusPlusLanguage::Terminate();
- GoLanguage::Terminate();
- JavaLanguage::Terminate();
ObjCLanguage::Terminate();
ObjCPlusPlusLanguage::Terminate();
- OCamlLanguage::Terminate();
#if defined(__APPLE__)
DynamicLoaderDarwinKernel::Terminate();
@@ -337,7 +321,6 @@ void SystemInitializerTest::Terminate() {
DynamicLoaderStatic::Terminate();
DynamicLoaderWindowsDYLD::Terminate();
- OperatingSystemGo::Terminate();
platform_freebsd::PlatformFreeBSD::Terminate();
platform_linux::PlatformLinux::Terminate();
@@ -353,6 +336,7 @@ void SystemInitializerTest::Terminate() {
PlatformDarwinKernel::Terminate();
#endif
+ breakpad::ObjectFileBreakpad::Terminate();
ObjectFileELF::Terminate();
ObjectFileMachO::Terminate();
ObjectFilePECOFF::Terminate();
diff --git a/tools/lldb-test/SystemInitializerTest.h b/tools/lldb-test/SystemInitializerTest.h
index 887d6243765d..5950ff725ff0 100644
--- a/tools/lldb-test/SystemInitializerTest.h
+++ b/tools/lldb-test/SystemInitializerTest.h
@@ -26,7 +26,7 @@ public:
SystemInitializerTest();
~SystemInitializerTest() override;
- void Initialize() override;
+ llvm::Error Initialize(const InitializerOptions &options) override;
void Terminate() override;
};
diff --git a/tools/lldb-test/lldb-test.cpp b/tools/lldb-test/lldb-test.cpp
index c9225f63d303..f7bfc487c0ce 100644
--- a/tools/lldb-test/lldb-test.cpp
+++ b/tools/lldb-test/lldb-test.cpp
@@ -30,6 +30,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/IntervalMap.h"
@@ -90,19 +91,27 @@ namespace object {
cl::opt<bool> SectionContents("contents",
cl::desc("Dump each section's contents"),
cl::sub(ObjectFileSubcommand));
+cl::opt<bool> SectionDependentModules("dep-modules",
+ cl::desc("Dump each dependent module"),
+ cl::sub(ObjectFileSubcommand));
cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"),
cl::OneOrMore,
cl::sub(ObjectFileSubcommand));
} // namespace object
namespace symbols {
-static cl::list<std::string> InputFilenames(cl::Positional,
- cl::desc("<input files>"),
- cl::OneOrMore,
- cl::sub(SymbolsSubcommand));
+static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),
+ cl::Required, cl::sub(SymbolsSubcommand));
+
+static cl::opt<std::string>
+ SymbolPath("symbol-file",
+ cl::desc("The file from which to fetch symbol information."),
+ cl::value_desc("file"), cl::sub(SymbolsSubcommand));
+
enum class FindType {
None,
Function,
+ Block,
Namespace,
Type,
Variable,
@@ -112,6 +121,7 @@ static cl::opt<FindType> Find(
cl::values(
clEnumValN(FindType::None, "none", "No search, just dump the module."),
clEnumValN(FindType::Function, "function", "Find functions."),
+ clEnumValN(FindType::Block, "block", "Find blocks."),
clEnumValN(FindType::Namespace, "namespace", "Find namespaces."),
clEnumValN(FindType::Type, "type", "Find types."),
clEnumValN(FindType::Variable, "variable", "Find global variables.")),
@@ -146,6 +156,10 @@ static FunctionNameType getFunctionNameFlags() {
return Result;
}
+static cl::opt<bool> DumpAST("dump-ast",
+ cl::desc("Dump AST restored from symbols."),
+ cl::sub(SymbolsSubcommand));
+
static cl::opt<bool> Verify("verify", cl::desc("Verify symbol information."),
cl::sub(SymbolsSubcommand));
@@ -158,10 +172,12 @@ static cl::opt<int> Line("line", cl::desc("Line to search."),
static Expected<CompilerDeclContext> getDeclContext(SymbolVendor &Vendor);
static Error findFunctions(lldb_private::Module &Module);
+static Error findBlocks(lldb_private::Module &Module);
static Error findNamespaces(lldb_private::Module &Module);
static Error findTypes(lldb_private::Module &Module);
static Error findVariables(lldb_private::Module &Module);
static Error dumpModule(lldb_private::Module &Module);
+static Error dumpAST(lldb_private::Module &Module);
static Error verify(lldb_private::Module &Module);
static Expected<Error (*)(lldb_private::Module &)> getAction();
@@ -197,7 +213,6 @@ struct IRMemoryMapTestState {
: Target(Target), Map(Target), Allocations(IntervalMapAllocator) {}
};
-bool areAllocationsOverlapping(const AllocationT &L, const AllocationT &R);
bool evalMalloc(StringRef Line, IRMemoryMapTestState &State);
bool evalFree(StringRef Line, IRMemoryMapTestState &State);
int evaluateMemoryMapCommands(Debugger &Dbg);
@@ -214,10 +229,9 @@ static Error make_string_error(const char *Format, Args &&... args) {
TargetSP opts::createTarget(Debugger &Dbg, const std::string &Filename) {
TargetSP Target;
- Status ST =
- Dbg.GetTargetList().CreateTarget(Dbg, Filename, /*triple*/ "",
- /*get_dependent_modules*/ false,
- /*platform_options*/ nullptr, Target);
+ Status ST = Dbg.GetTargetList().CreateTarget(
+ Dbg, Filename, /*triple*/ "", eLoadDependentsNo,
+ /*platform_options*/ nullptr, Target);
if (ST.Fail()) {
errs() << formatv("Failed to create target '{0}: {1}\n", Filename, ST);
exit(1);
@@ -278,7 +292,7 @@ std::string opts::breakpoint::substitute(StringRef Cmd) {
OS << sys::path::parent_path(breakpoint::CommandFile);
break;
}
- // fall through
+ LLVM_FALLTHROUGH;
default:
size_t pos = Cmd.find('%');
OS << Cmd.substr(0, pos);
@@ -340,7 +354,7 @@ Error opts::symbols::findFunctions(lldb_private::Module &Module) {
if (!File.empty()) {
assert(Line != 0);
- FileSpec src_file(File, false);
+ FileSpec src_file(File);
size_t cu_count = Module.GetNumCompileUnits();
for (size_t i = 0; i < cu_count; i++) {
lldb::CompUnitSP cu_sp = Module.GetCompileUnitAtIndex(i);
@@ -383,6 +397,42 @@ Error opts::symbols::findFunctions(lldb_private::Module &Module) {
return Error::success();
}
+Error opts::symbols::findBlocks(lldb_private::Module &Module) {
+ assert(!Regex);
+ assert(!File.empty());
+ assert(Line != 0);
+
+ SymbolContextList List;
+
+ FileSpec src_file(File);
+ size_t cu_count = Module.GetNumCompileUnits();
+ for (size_t i = 0; i < cu_count; i++) {
+ lldb::CompUnitSP cu_sp = Module.GetCompileUnitAtIndex(i);
+ if (!cu_sp)
+ continue;
+
+ LineEntry le;
+ cu_sp->FindLineEntry(0, Line, &src_file, false, &le);
+ if (!le.IsValid())
+ continue;
+
+ auto addr = le.GetSameLineContiguousAddressRange().GetBaseAddress();
+ if (!addr.IsValid())
+ continue;
+
+ SymbolContext sc;
+ uint32_t resolved = addr.CalculateSymbolContext(&sc, eSymbolContextBlock);
+ if (resolved & eSymbolContextBlock)
+ List.Append(sc);
+ }
+
+ outs() << formatv("Found {0} blocks:\n", List.GetSize());
+ StreamString Stream;
+ List.Dump(&Stream, nullptr);
+ outs() << Stream.GetData() << "\n";
+ return Error::success();
+}
+
Error opts::symbols::findNamespaces(lldb_private::Module &Module) {
SymbolVendor &Vendor = *Module.GetSymbolVendor();
Expected<CompilerDeclContext> ContextOr = getDeclContext(Vendor);
@@ -391,9 +441,8 @@ Error opts::symbols::findNamespaces(lldb_private::Module &Module) {
CompilerDeclContext *ContextPtr =
ContextOr->IsValid() ? &*ContextOr : nullptr;
- SymbolContext SC;
CompilerDeclContext Result =
- Vendor.FindNamespace(SC, ConstString(Name), ContextPtr);
+ Vendor.FindNamespace(ConstString(Name), ContextPtr);
if (Result)
outs() << "Found namespace: "
<< Result.GetScopeQualifiedName().GetStringRef() << "\n";
@@ -410,10 +459,9 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
CompilerDeclContext *ContextPtr =
ContextOr->IsValid() ? &*ContextOr : nullptr;
- SymbolContext SC;
DenseSet<SymbolFile *> SearchedFiles;
TypeMap Map;
- Vendor.FindTypes(SC, ConstString(Name), ContextPtr, true, UINT32_MAX,
+ Vendor.FindTypes(ConstString(Name), ContextPtr, true, UINT32_MAX,
SearchedFiles, Map);
outs() << formatv("Found {0} types:\n", Map.GetSize());
@@ -470,6 +518,32 @@ Error opts::symbols::dumpModule(lldb_private::Module &Module) {
return Error::success();
}
+Error opts::symbols::dumpAST(lldb_private::Module &Module) {
+ SymbolVendor &plugin = *Module.GetSymbolVendor();
+ Module.ParseAllDebugSymbols();
+
+ auto symfile = plugin.GetSymbolFile();
+ if (!symfile)
+ return make_string_error("Module has no symbol file.");
+
+ auto clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
+ symfile->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus));
+ if (!clang_ast_ctx)
+ return make_string_error("Can't retrieve Clang AST context.");
+
+ auto ast_ctx = clang_ast_ctx->getASTContext();
+ if (!ast_ctx)
+ return make_string_error("Can't retrieve AST context.");
+
+ auto tu = ast_ctx->getTranslationUnitDecl();
+ if (!tu)
+ return make_string_error("Can't retrieve translation unit declaration.");
+
+ tu->print(outs());
+
+ return Error::success();
+}
+
Error opts::symbols::verify(lldb_private::Module &Module) {
SymbolVendor &plugin = *Module.GetSymbolVendor();
@@ -523,6 +597,10 @@ Error opts::symbols::verify(lldb_private::Module &Module) {
}
Expected<Error (*)(lldb_private::Module &)> opts::symbols::getAction() {
+ if (Verify && DumpAST)
+ return make_string_error(
+ "Cannot both verify symbol information and dump AST.");
+
if (Verify) {
if (Find != FindType::None)
return make_string_error(
@@ -535,6 +613,17 @@ Expected<Error (*)(lldb_private::Module &)> opts::symbols::getAction() {
return verify;
}
+ if (DumpAST) {
+ if (Find != FindType::None)
+ return make_string_error("Cannot both search and dump AST.");
+ if (Regex || !Context.empty() || !Name.empty() || !File.empty() ||
+ Line != 0)
+ return make_string_error(
+ "-regex, -context, -name, -file and -line options are not "
+ "applicable for dumping AST.");
+ return dumpAST;
+ }
+
if (Regex && !Context.empty())
return make_string_error(
"Cannot search using both regular expressions and context.");
@@ -566,6 +655,15 @@ Expected<Error (*)(lldb_private::Module &)> opts::symbols::getAction() {
"when searching a function.");
return findFunctions;
+ case FindType::Block:
+ if (File.empty() || Line == 0)
+ return make_string_error("Both file name and line number must be "
+ "specified when searching a block.");
+ if (Regex || getFunctionNameFlags() != 0)
+ return make_string_error("Cannot use regular expression or "
+ "function-flags for searching a block.");
+ return findBlocks;
+
case FindType::Namespace:
if (Regex || !File.empty() || Line != 0)
return make_string_error("Cannot search for namespaces using regular "
@@ -584,6 +682,8 @@ Expected<Error (*)(lldb_private::Module &)> opts::symbols::getAction() {
"using line numbers.");
return findVariables;
}
+
+ llvm_unreachable("Unsupported symbol action.");
}
int opts::symbols::dumpSymbols(Debugger &Dbg) {
@@ -594,28 +694,59 @@ int opts::symbols::dumpSymbols(Debugger &Dbg) {
}
auto Action = *ActionOr;
- int HadErrors = 0;
- for (const auto &File : InputFilenames) {
- outs() << "Module: " << File << "\n";
- ModuleSpec Spec{FileSpec(File, false)};
- Spec.GetSymbolFileSpec().SetFile(File, false, FileSpec::Style::native);
+ outs() << "Module: " << InputFile << "\n";
+ ModuleSpec Spec{FileSpec(InputFile)};
+ StringRef Symbols = SymbolPath.empty() ? InputFile : SymbolPath;
+ Spec.GetSymbolFileSpec().SetFile(Symbols, FileSpec::Style::native);
- auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
- SymbolVendor *Vendor = ModulePtr->GetSymbolVendor();
- if (!Vendor) {
- WithColor::error() << "Module has no symbol vendor.\n";
- HadErrors = 1;
- continue;
- }
+ auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
+ SymbolVendor *Vendor = ModulePtr->GetSymbolVendor();
+ if (!Vendor) {
+ WithColor::error() << "Module has no symbol vendor.\n";
+ return 1;
+ }
- if (Error E = Action(*ModulePtr)) {
- WithColor::error() << toString(std::move(E)) << "\n";
- HadErrors = 1;
+ if (Error E = Action(*ModulePtr)) {
+ WithColor::error() << toString(std::move(E)) << "\n";
+ return 1;
+ }
+
+ return 0;
+}
+
+static void dumpSectionList(LinePrinter &Printer, const SectionList &List, bool is_subsection) {
+ size_t Count = List.GetNumSections(0);
+ if (Count == 0) {
+ Printer.formatLine("There are no {0}sections", is_subsection ? "sub" : "");
+ return;
+ }
+ Printer.formatLine("Showing {0} {1}sections", Count,
+ is_subsection ? "sub" : "");
+ for (size_t I = 0; I < Count; ++I) {
+ auto S = List.GetSectionAtIndex(I);
+ assert(S);
+ AutoIndent Indent(Printer, 2);
+ Printer.formatLine("Index: {0}", I);
+ Printer.formatLine("ID: {0:x}", S->GetID());
+ Printer.formatLine("Name: {0}", S->GetName().GetStringRef());
+ Printer.formatLine("Type: {0}", S->GetTypeAsCString());
+ Printer.formatLine("Permissions: {0}", GetPermissionsAsCString(S->GetPermissions()));
+ Printer.formatLine("Thread specific: {0:y}", S->IsThreadSpecific());
+ Printer.formatLine("VM address: {0:x}", S->GetFileAddress());
+ Printer.formatLine("VM size: {0}", S->GetByteSize());
+ Printer.formatLine("File size: {0}", S->GetFileSize());
+
+ if (opts::object::SectionContents) {
+ DataExtractor Data;
+ S->GetSectionData(Data);
+ ArrayRef<uint8_t> Bytes = {Data.GetDataStart(), Data.GetDataEnd()};
+ Printer.formatBinary("Data: ", Bytes, 0);
}
- outs().flush();
+ if (S->GetType() == eSectionTypeContainer)
+ dumpSectionList(Printer, S->GetChildren(), true);
+ Printer.NewLine();
}
- return HadErrors;
}
static int dumpObjectFiles(Debugger &Dbg) {
@@ -623,9 +754,17 @@ static int dumpObjectFiles(Debugger &Dbg) {
int HadErrors = 0;
for (const auto &File : opts::object::InputFilenames) {
- ModuleSpec Spec{FileSpec(File, false)};
+ ModuleSpec Spec{FileSpec(File)};
auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
+
+ ObjectFile *ObjectPtr = ModulePtr->GetObjectFile();
+ if (!ObjectPtr) {
+ WithColor::error() << File << " not recognised as an object file\n";
+ HadErrors = 1;
+ continue;
+ }
+
// Fetch symbol vendor before we get the section list to give the symbol
// vendor a chance to populate it.
ModulePtr->GetSymbolVendor();
@@ -636,27 +775,29 @@ static int dumpObjectFiles(Debugger &Dbg) {
continue;
}
+ Printer.formatLine("Plugin name: {0}", ObjectPtr->GetPluginName());
Printer.formatLine("Architecture: {0}",
ModulePtr->GetArchitecture().GetTriple().getTriple());
Printer.formatLine("UUID: {0}", ModulePtr->GetUUID().GetAsString());
-
- size_t Count = Sections->GetNumSections(0);
- Printer.formatLine("Showing {0} sections", Count);
- for (size_t I = 0; I < Count; ++I) {
- AutoIndent Indent(Printer, 2);
- auto S = Sections->GetSectionAtIndex(I);
- assert(S);
- Printer.formatLine("Index: {0}", I);
- Printer.formatLine("Name: {0}", S->GetName().GetStringRef());
- Printer.formatLine("Type: {0}", S->GetTypeAsCString());
- Printer.formatLine("VM size: {0}", S->GetByteSize());
- Printer.formatLine("File size: {0}", S->GetFileSize());
-
- if (opts::object::SectionContents) {
- DataExtractor Data;
- S->GetSectionData(Data);
- ArrayRef<uint8_t> Bytes = {Data.GetDataStart(), Data.GetDataEnd()};
- Printer.formatBinary("Data: ", Bytes, 0);
+ Printer.formatLine("Executable: {0}", ObjectPtr->IsExecutable());
+ Printer.formatLine("Stripped: {0}", ObjectPtr->IsStripped());
+ Printer.formatLine("Type: {0}", ObjectPtr->GetType());
+ Printer.formatLine("Strata: {0}", ObjectPtr->GetStrata());
+ Printer.formatLine("Base VM address: {0:x}",
+ ObjectPtr->GetBaseAddress().GetFileAddress());
+
+ dumpSectionList(Printer, *Sections, /*is_subsection*/ false);
+
+ if (opts::object::SectionDependentModules) {
+ // A non-empty section list ensures a valid object file.
+ auto Obj = ModulePtr->GetObjectFile();
+ FileSpecList Files;
+ auto Count = Obj->GetDependentModules(Files);
+ Printer.formatLine("Showing {0} dependent module(s)", Count);
+ for (size_t I = 0; I < Files.GetSize(); ++I) {
+ AutoIndent Indent(Printer, 2);
+ Printer.formatLine("Name: {0}",
+ Files.GetFileSpecAtIndex(I).GetCString());
}
Printer.NewLine();
}
@@ -664,13 +805,6 @@ static int dumpObjectFiles(Debugger &Dbg) {
return HadErrors;
}
-/// Check if two half-open intervals intersect:
-/// http://world.std.com/~swmcd/steven/tech/interval.html
-bool opts::irmemorymap::areAllocationsOverlapping(const AllocationT &L,
- const AllocationT &R) {
- return R.first < L.second && L.first < R.second;
-}
-
bool opts::irmemorymap::evalMalloc(StringRef Line,
IRMemoryMapTestState &State) {
// ::= <label> = malloc <size> <alignment>
@@ -717,28 +851,21 @@ bool opts::irmemorymap::evalMalloc(StringRef Line,
exit(1);
}
- // Check that the allocation does not overlap another allocation. Do so by
- // testing each allocation which may cover the interval [Addr, EndOfRegion).
- addr_t EndOfRegion = Addr + Size;
- auto Probe = State.Allocations.begin();
- Probe.advanceTo(Addr); //< First interval s.t stop >= Addr.
- AllocationT NewAllocation = {Addr, EndOfRegion};
- while (Probe != State.Allocations.end() && Probe.start() < EndOfRegion) {
- AllocationT ProbeAllocation = {Probe.start(), Probe.stop()};
- if (areAllocationsOverlapping(ProbeAllocation, NewAllocation)) {
- outs() << "Malloc error: overlapping allocation detected"
- << formatv(", previous allocation at [{0:x}, {1:x})\n",
- Probe.start(), Probe.stop());
- exit(1);
- }
- ++Probe;
+ // In case of Size == 0, we still expect the returned address to be unique and
+ // non-overlapping.
+ addr_t EndOfRegion = Addr + std::max<size_t>(Size, 1);
+ if (State.Allocations.overlaps(Addr, EndOfRegion)) {
+ auto I = State.Allocations.find(Addr);
+ outs() << "Malloc error: overlapping allocation detected"
+ << formatv(", previous allocation at [{0:x}, {1:x})\n", I.start(),
+ I.stop());
+ exit(1);
}
- // Insert the new allocation into the interval map. Use unique allocation IDs
- // to inhibit interval coalescing.
+ // Insert the new allocation into the interval map. Use unique allocation
+ // IDs to inhibit interval coalescing.
static unsigned AllocationID = 0;
- if (Size)
- State.Allocations.insert(Addr, EndOfRegion, AllocationID++);
+ State.Allocations.insert(Addr, EndOfRegion, AllocationID++);
// Store the label -> address mapping.
State.Label2AddrMap[Label] = Addr;
@@ -836,8 +963,13 @@ int main(int argc, const char *argv[]) {
cl::ParseCommandLineOptions(argc, argv, "LLDB Testing Utility\n");
SystemLifetimeManager DebuggerLifetime;
- DebuggerLifetime.Initialize(llvm::make_unique<SystemInitializerTest>(),
- nullptr);
+ if (auto e = DebuggerLifetime.Initialize(
+ llvm::make_unique<SystemInitializerTest>(), {}, nullptr)) {
+ WithColor::error() << "initialization failed: " << toString(std::move(e))
+ << '\n';
+ return 1;
+ }
+
CleanUp TerminateDebugger([&] { DebuggerLifetime.Terminate(); });
auto Dbg = lldb_private::Debugger::CreateInstance();