-
Notifications
You must be signed in to change notification settings - Fork 15k
[llvm][dwarfdump] Add --child-tags option to filter by DWARF tags #165720
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-llvm-binary-utilities @llvm/pr-subscribers-debuginfo Author: Michael Buch (Michael137) ChangesThis patch adds a new option Motivating examples are:
For tags not known to dwarfdump, we pretend that the tag wasn't specified. Note, this flag only takes effect when Example: Full diff: https://github.com/llvm/llvm-project/pull/165720.diff 3 Files Affected:
diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h
index e7e87bbfebf38..32ce4520dbca7 100644
--- a/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/llvm/include/llvm/DebugInfo/DIContext.h
@@ -202,6 +202,8 @@ struct DIDumpOptions {
bool ShowAddresses = true;
bool ShowChildren = false;
bool ShowParents = false;
+ /// List of DWARF tags to filter children by.
+ llvm::SmallVector<unsigned> ChildTagsFilter;
bool ShowForm = false;
bool SummarizeTypes = false;
bool Verbose = false;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index db5cc37c93f90..7558fbda18459 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -676,7 +676,9 @@ void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
DIDumpOptions ChildDumpOpts = DumpOpts;
ChildDumpOpts.ShowParents = false;
while (Child) {
- Child.dump(OS, Indent + 2, ChildDumpOpts);
+ if (DumpOpts.ChildTagsFilter.empty() ||
+ llvm::is_contained(DumpOpts.ChildTagsFilter, Child.getTag()))
+ Child.dump(OS, Indent + 2, ChildDumpOpts);
Child = Child.getSibling();
}
}
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 79f05278c329d..eb5f8b4af95a6 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -14,6 +14,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVectorExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
@@ -241,6 +242,15 @@ static opt<bool>
cat(DwarfDumpCategory));
static alias ShowParentsAlias("p", desc("Alias for --show-parents."),
aliasopt(ShowParents), cl::NotHidden);
+
+static list<std::string>
+ ChildTags("child-tags",
+ desc("When --show-children is specified, show only DIEs with the "
+ "specified DWARF tags."),
+ value_desc("list of DWARF tags"), cat(DwarfDumpCategory));
+static alias TagsAlias("t", desc("Alias for --child-tags."),
+ aliasopt(ChildTags), cl::NotHidden);
+
static opt<bool>
ShowForm("show-form",
desc("Show DWARF form types after the DWARF attribute types."),
@@ -329,6 +339,13 @@ static cl::extrahelp
/// @}
//===----------------------------------------------------------------------===//
+static llvm::SmallVector<unsigned>
+makeTagVector(const list<std::string> &TagStrings) {
+ return llvm::map_to_vector(TagStrings, [](const std::string &Tag) {
+ return llvm::dwarf::getTag(Tag);
+ });
+}
+
static void error(Error Err) {
if (!Err)
return;
@@ -355,6 +372,7 @@ static DIDumpOptions getDumpOpts(DWARFContext &C) {
DumpOpts.ShowAddresses = !Diff;
DumpOpts.ShowChildren = ShowChildren;
DumpOpts.ShowParents = ShowParents;
+ DumpOpts.ChildTagsFilter = makeTagVector(ChildTags);
DumpOpts.ShowForm = ShowForm;
DumpOpts.SummarizeTypes = SummarizeTypes;
DumpOpts.Verbose = Verbose;
@@ -898,6 +916,12 @@ int main(int argc, char **argv) {
Find.empty() && !FindAllApple)
ShowChildren = true;
+ if (!ShowChildren && !ChildTags.empty()) {
+ WithColor::error()
+ << "incompatible arguments: --child-tags requires --show-children";
+ return 1;
+ }
+
// Defaults to a.out if no filenames specified.
if (InputFilenames.empty())
InputFilenames.push_back("a.out");
|
|
Seems OK to me as a feature - though I wonder if we're getting to the point of "should have an arbitrary query language" for querying DWARF at this point? (did we ever end up with the json output for dwarfdump? perhaps that's the way to do it - dump to json and use jquery?) |
i had the exact same line of thought when i initially started implementing this. What nudged me over the edge was that i prefer looking at dwarfdump output over json, though that’s admittedly a selfish reason. Ultimately i thought, if it’s not too much of a maintenance burden, might as well. Of course there’s always complexity of how various options interact, which in this case seemed ok. A more involved querying feature (like filtering by attribute value/existence), which I’d love to have, is probably not worth adding to the current infrastructure because of how complex it would be to implement (afaict). But yea, happy to hear others chime in on usefulness/if it’s acceptable maintenance-wise, and whether there is appetite for something more complete. |
|
I would have probably called it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't remember how we generate the dwarfdump manpage, but can you make to update it, too? (Unless we generate it from the --help output)
| @@ -202,6 +202,8 @@ struct DIDumpOptions { | |||
| bool ShowAddresses = true; | |||
| bool ShowChildren = false; | |||
| bool ShowParents = false; | |||
| /// List of DWARF tags to filter children by. | |||
| llvm::SmallVector<unsigned> ChildTagsFilter; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this is going to be empty most of the time, maybe just use a vector or a SmallVector<0 or 1>?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How are multiple ones separated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like with other options, you specify the option multiple times. E.g., dwarfdump -t DW_TAG_foo -t DW_TAG_bar
Other options like --name behave the same
This patch adds a new option `--child-tags` (`-t` for short), which makes dwarfdump only dump children whose DWARF tag is in the list of tags specified by the user. Motivating examples are: * dumping all global variables in a CU * dumping all non-static data members of a structure * dumping all module import declarations of a CU * etc. For tags not known to dwarfdump, we pretend that the tag wasn't specified.
72a3f5b to
3d92747
Compare
This patch adds a new option
--child-tags(-tfor short), which makes dwarfdump only dump children whose DWARF tag is in the list of tags specified by the user.Motivating examples are:
For tags not known to dwarfdump, we pretend that the tag wasn't specified.
Note, this flag only takes effect when
--show-childrenis set (either explicitly or implicitly). We error out when trying to use the flag without dumping children.Example: