summaryrefslogtreecommitdiffstats
path: root/lldb/tools
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2018-06-12 12:57:36 +0000
committerPavel Labath <labath@google.com>2018-06-12 12:57:36 +0000
commite6954cb2a1819abe0dd3b7cd46b41bc28302f155 (patch)
tree781fe55ee89ef8d8fec0253c03800653f18017be /lldb/tools
parent3d671248abc0949fad063a390fba8c17aa545a40 (diff)
downloadbcm5719-llvm-e6954cb2a1819abe0dd3b7cd46b41bc28302f155.tar.gz
bcm5719-llvm-e6954cb2a1819abe0dd3b7cd46b41bc28302f155.zip
lldb-test symbols: Add -file argument and the ability to dump global variables in a file
The motivation for this is to be able to Dwarf index ability to look up variables within a given compilation unit. It also fits in with the patch in progress at D47939, which will add the ability to look up funtions using file+line pairs. The verification of which lldb-test options can be used together was getting a bit unwieldy, so I moved the logic out into a separate function. llvm-svn: 334498
Diffstat (limited to 'lldb/tools')
-rw-r--r--lldb/tools/lldb-test/lldb-test.cpp174
1 files changed, 101 insertions, 73 deletions
diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp
index c37d56ae7d0..223ee6b91a3 100644
--- a/lldb/tools/lldb-test/lldb-test.cpp
+++ b/lldb/tools/lldb-test/lldb-test.cpp
@@ -148,6 +148,10 @@ static FunctionNameType getFunctionNameFlags() {
static cl::opt<bool> Verify("verify", cl::desc("Verify symbol information."),
cl::sub(SymbolsSubcommand));
+static cl::opt<std::string> File("file",
+ cl::desc("File (compile unit) to search."),
+ cl::sub(SymbolsSubcommand));
+
static Expected<CompilerDeclContext> getDeclContext(SymbolVendor &Vendor);
static Error findFunctions(lldb_private::Module &Module);
@@ -157,6 +161,7 @@ static Error findVariables(lldb_private::Module &Module);
static Error dumpModule(lldb_private::Module &Module);
static Error verify(lldb_private::Module &Module);
+static Expected<Error (&)(lldb_private::Module &)> getAction();
static int dumpSymbols(Debugger &Dbg);
}
@@ -197,6 +202,13 @@ int evaluateMemoryMapCommands(Debugger &Dbg);
} // namespace opts
+template <typename... Args>
+static Error make_string_error(const char *Format, Args &&... args) {
+ return llvm::make_error<llvm::StringError>(
+ llvm::formatv(Format, std::forward<Args>(args)...).str(),
+ llvm::inconvertibleErrorCode());
+}
+
TargetSP opts::createTarget(Debugger &Dbg, const std::string &Filename) {
TargetSP Target;
Status ST =
@@ -312,14 +324,10 @@ opts::symbols::getDeclContext(SymbolVendor &Vendor) {
return CompilerDeclContext();
VariableList List;
Vendor.FindGlobalVariables(ConstString(Context), nullptr, UINT32_MAX, List);
- if (List.Empty()) {
- return make_error<StringError>("Context search didn't find a match.",
- inconvertibleErrorCode());
- }
- if (List.GetSize() > 1) {
- return make_error<StringError>("Context search found multiple matches.",
- inconvertibleErrorCode());
- }
+ if (List.Empty())
+ return make_string_error("Context search didn't find a match.");
+ if (List.GetSize() > 1)
+ return make_string_error("Context search found multiple matches.");
return List.GetVariableAtIndex(0)->GetDeclContext();
}
@@ -394,6 +402,22 @@ Error opts::symbols::findVariables(lldb_private::Module &Module) {
RegularExpression RE(Name);
assert(RE.IsValid());
Vendor.FindGlobalVariables(RE, UINT32_MAX, List);
+ } else if (!File.empty()) {
+ CompUnitSP CU;
+ for (size_t Ind = 0; !CU && Ind < Module.GetNumCompileUnits(); ++Ind) {
+ CompUnitSP Candidate = Module.GetCompileUnitAtIndex(Ind);
+ if (!Candidate || Candidate->GetFilename().GetStringRef() != File)
+ continue;
+ if (CU)
+ return make_string_error("Multiple compile units for file `{0}` found.",
+ File);
+ CU = std::move(Candidate);
+ }
+
+ if (!CU)
+ return make_string_error("Compile unit `{0}` not found.", File);
+
+ List.AddVariables(CU->GetVariableList(true).get());
} else {
Expected<CompilerDeclContext> ContextOr = getDeclContext(Vendor);
if (!ContextOr)
@@ -419,15 +443,11 @@ Error opts::symbols::dumpModule(lldb_private::Module &Module) {
}
Error opts::symbols::verify(lldb_private::Module &Module) {
- SymbolVendor *plugin = Module.GetSymbolVendor();
- if (!plugin)
- return make_error<StringError>("Can't get a symbol vendor.",
- inconvertibleErrorCode());
+ SymbolVendor &plugin = *Module.GetSymbolVendor();
- SymbolFile *symfile = plugin->GetSymbolFile();
+ SymbolFile *symfile = plugin.GetSymbolFile();
if (!symfile)
- return make_error<StringError>("Can't get a symbol file.",
- inconvertibleErrorCode());
+ return make_string_error("Module has no symbol file.");
uint32_t comp_units_count = symfile->GetNumCompileUnits();
@@ -436,17 +456,14 @@ Error opts::symbols::verify(lldb_private::Module &Module) {
for (uint32_t i = 0; i < comp_units_count; i++) {
lldb::CompUnitSP comp_unit = symfile->ParseCompileUnitAtIndex(i);
if (!comp_unit)
- return make_error<StringError>("Can't get a compile unit.",
- inconvertibleErrorCode());
+ return make_string_error("Connot parse compile unit {0}.", i);
outs() << "Processing '" << comp_unit->GetFilename().AsCString() <<
"' compile unit.\n";
LineTable *lt = comp_unit->GetLineTable();
if (!lt)
- return make_error<StringError>(
- "Can't get a line table of a compile unit.",
- inconvertibleErrorCode());
+ return make_string_error("Can't get a line table of a compile unit.");
uint32_t count = lt->GetSize();
@@ -457,23 +474,18 @@ Error opts::symbols::verify(lldb_private::Module &Module) {
LineEntry le;
if (!lt->GetLineEntryAtIndex(0, le))
- return make_error<StringError>(
- "Can't get a line entry of a compile unit",
- inconvertibleErrorCode());
+ return make_string_error("Can't get a line entry of a compile unit.");
for (uint32_t i = 1; i < count; i++) {
lldb::addr_t curr_end =
le.range.GetBaseAddress().GetFileAddress() + le.range.GetByteSize();
if (!lt->GetLineEntryAtIndex(i, le))
- return make_error<StringError>(
- "Can't get a line entry of a compile unit",
- inconvertibleErrorCode());
+ return make_string_error("Can't get a line entry of a compile unit");
if (curr_end > le.range.GetBaseAddress().GetFileAddress())
- return make_error<StringError>(
- "Line table of a compile unit is inconsistent",
- inconvertibleErrorCode());
+ return make_string_error(
+ "Line table of a compile unit is inconsistent.");
}
}
@@ -482,53 +494,69 @@ Error opts::symbols::verify(lldb_private::Module &Module) {
return Error::success();
}
-int opts::symbols::dumpSymbols(Debugger &Dbg) {
- if (Verify && Find != FindType::None) {
- WithColor::error() << "Cannot both search and verify symbol information.\n";
- return 1;
- }
- if (Find != FindType::None && Regex && !Context.empty()) {
- WithColor::error()
- << "Cannot search using both regular expressions and context.\n";
- return 1;
- }
- if ((Find == FindType::Type || Find == FindType::Namespace) && Regex) {
- WithColor::error() << "Cannot search for types and namespaces using "
- "regular expressions.\n";
- return 1;
+Expected<Error (&)(lldb_private::Module &)> opts::symbols::getAction() {
+ if (Verify) {
+ if (Find != FindType::None)
+ return make_string_error(
+ "Cannot both search and verify symbol information.");
+ if (Regex || !Context.empty() || !Name.empty() || !File.empty())
+ return make_string_error("-regex, -context, -name and -file options are not "
+ "applicable for symbol verification.");
+ return verify;
}
- if (Find == FindType::Function && Regex && getFunctionNameFlags() != 0) {
- WithColor::error() << "Cannot search for types using both regular "
- "expressions and function-flags.\n";
- return 1;
+
+ if (Regex && !Context.empty())
+ return make_string_error(
+ "Cannot search using both regular expressions and context.");
+
+ if (Regex && !RegularExpression(Name).IsValid())
+ return make_string_error("`{0}` is not a valid regular expression.", Name);
+
+ if (Regex + !Context.empty() + !File.empty() >= 2)
+ return make_string_error(
+ "Only one of -regex, -context and -file may be used simultaneously.");
+ if (Regex && Name.empty())
+ return make_string_error("-regex used without a -name");
+
+ switch (Find) {
+ case FindType::None:
+ if (!Context.empty() || !Name.empty() || !File.empty())
+ return make_string_error(
+ "Specify search type (-find) to use search options.");
+ return dumpModule;
+
+ case FindType::Function:
+ if (!File.empty())
+ return make_string_error("Cannot search for functions by file name.");
+ if (Regex && getFunctionNameFlags() != 0)
+ return make_string_error("Cannot search for functions using both regular "
+ "expressions and function-flags.");
+ return findFunctions;
+
+ case FindType::Namespace:
+ if (Regex || !File.empty())
+ return make_string_error("Cannot search for namespaces using regular "
+ "expressions or file names.");
+ return findNamespaces;
+
+ case FindType::Type:
+ if (Regex || !File.empty())
+ return make_string_error("Cannot search for types using regular "
+ "expressions or file names.");
+ return findTypes;
+
+ case FindType::Variable:
+ return findVariables;
}
- if (Regex && !RegularExpression(Name).IsValid()) {
- WithColor::error() << "`" << Name
- << "` is not a valid regular expression.\n";
+}
+
+int opts::symbols::dumpSymbols(Debugger &Dbg) {
+ auto ActionOr = getAction();
+ if (!ActionOr) {
+ logAllUnhandledErrors(ActionOr.takeError(), WithColor::error(), "");
return 1;
}
-
- Error (*Action)(lldb_private::Module &);
- if (!Verify) {
- switch (Find) {
- case FindType::Function:
- Action = findFunctions;
- break;
- case FindType::Namespace:
- Action = findNamespaces;
- break;
- case FindType::Type:
- Action = findTypes;
- break;
- case FindType::Variable:
- Action = findVariables;
- break;
- case FindType::None:
- Action = dumpModule;
- break;
- }
- } else
- Action = verify;
+ auto Action = *ActionOr;
int HadErrors = 0;
for (const auto &File : InputFilenames) {
@@ -543,7 +571,7 @@ int opts::symbols::dumpSymbols(Debugger &Dbg) {
HadErrors = 1;
continue;
}
-
+
if (Error E = Action(*ModulePtr)) {
WithColor::error() << toString(std::move(E)) << "\n";
HadErrors = 1;
OpenPOWER on IntegriCloud