Prep 1.29
[dwarves.git] / pdwtags.c
blob962883d2ca7c663f1aca159b5dd713549b16ad8e
1 /*
2 SPDX-License-Identifier: GPL-2.0-only
4 Copyright (C) 2007-2016 Arnaldo Carvalho de Melo <acme@kernel.org>
5 */
7 #include <argp.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <malloc.h>
12 #include "dwarves.h"
13 #include "dutil.h"
15 static struct conf_fprintf conf = {
16 .emit_stats = 1,
19 static void emit_tag(struct tag *tag, uint32_t tag_id, struct cu *cu)
21 printf("/* %d */\n", tag_id);
23 if (tag__is_struct(tag))
24 class__find_holes(tag__class(tag));
26 if (tag->tag == DW_TAG_base_type) {
27 char bf[64];
28 const char *name = base_type__name(tag__base_type(tag), bf, sizeof(bf));
30 if (name == NULL)
31 printf("anonymous base_type\n");
32 else
33 puts(name);
34 } else if (tag__is_pointer(tag))
35 printf(" /* pointer to %lld */\n", (unsigned long long)tag->type);
36 else
37 tag__fprintf(tag, cu, &conf, stdout);
39 printf(" /* size: %zd */\n\n", tag__size(tag, cu));
42 static int cu__emit_tags(struct cu *cu)
44 uint32_t i;
45 struct tag *tag;
47 puts("/* Types: */\n");
48 cu__for_each_type(cu, i, tag)
49 emit_tag(tag, i, cu);
51 puts("/* Functions: */\n");
52 conf.no_semicolon = true;
53 struct function *function;
54 cu__for_each_function(cu, i, function) {
55 tag__fprintf(function__tag(function), cu, &conf, stdout);
56 putchar('\n');
57 lexblock__fprintf(&function->lexblock, cu, function, 0,
58 &conf, stdout);
59 printf(" /* size: %zd */\n\n",
60 tag__size(function__tag(function), cu));
62 conf.no_semicolon = false;
64 puts("\n\n/* Variables: */\n");
65 cu__for_each_variable(cu, i, tag) {
66 tag__fprintf(tag, cu, NULL, stdout);
67 printf(" /* size: %zd */\n\n", tag__size(tag, cu));
70 puts("\n\n/* Constants: */\n");
71 cu__for_each_constant(cu, i, tag) {
72 tag__fprintf(tag, cu, NULL, stdout);
73 printf(" /* size: %zd */\n\n", tag__size(tag, cu));
76 bool first_namespace = true;
78 cu__for_each_namespace(cu, i, tag) {
79 if (!tag->top_level)
80 continue;
82 if (first_namespace) {
83 puts("\n\n/* Namespaces: */\n");
84 first_namespace = false;
86 tag__fprintf(tag, cu, NULL, stdout);
87 puts("\n");
90 return 0;
93 static enum load_steal_kind pdwtags_stealer(struct cu *cu,
94 struct conf_load *conf_load __maybe_unused)
96 cu__emit_tags(cu);
97 return LSK__DELETE;
100 static struct conf_load pdwtags_conf_load = {
101 .steal = pdwtags_stealer,
102 .conf_fprintf = &conf,
105 /* Name and version of program. */
106 ARGP_PROGRAM_VERSION_HOOK_DEF = dwarves_print_version;
108 static const struct argp_option pdwtags__options[] = {
110 .name = "format_path",
111 .key = 'F',
112 .arg = "FORMAT_LIST",
113 .doc = "List of debugging formats to try"
116 .key = 'V',
117 .name = "verbose",
118 .doc = "show details",
121 .name = NULL,
125 static error_t pdwtags__options_parser(int key, char *arg __maybe_unused,
126 struct argp_state *state)
128 switch (key) {
129 case ARGP_KEY_INIT:
130 if (state->child_inputs != NULL)
131 state->child_inputs[0] = state->input;
132 break;
133 case 'F': pdwtags_conf_load.format_path = arg; break;
134 case 'V': conf.show_decl_info = 1; break;
135 default: return ARGP_ERR_UNKNOWN;
137 return 0;
140 static const char pdwtags__args_doc[] = "FILE";
142 static struct argp pdwtags__argp = {
143 .options = pdwtags__options,
144 .parser = pdwtags__options_parser,
145 .args_doc = pdwtags__args_doc,
148 int main(int argc, char *argv[])
150 int remaining, rc = EXIT_FAILURE, err;
151 struct cus *cus = cus__new();
153 if (dwarves__init() || cus == NULL) {
154 fputs("pwdtags: insufficient memory\n", stderr);
155 goto out;
158 dwarves__resolve_cacheline_size(&pdwtags_conf_load, 0);
160 if (argp_parse(&pdwtags__argp, argc, argv, 0, &remaining, NULL) ||
161 remaining == argc) {
162 argp_help(&pdwtags__argp, stderr, ARGP_HELP_SEE, argv[0]);
163 goto out;
166 err = cus__load_files(cus, &pdwtags_conf_load, argv + remaining);
167 if (err == 0) {
168 rc = EXIT_SUCCESS;
169 goto out;
172 cus__fprintf_load_files_err(cus, "pdwtags", argv + remaining, err, stderr);
173 out:
174 cus__delete(cus);
175 dwarves__exit();
176 return rc;