2 * SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2007 Davi E. M. Arnaut <davi@haxent.com.br>
20 static struct conf_fprintf conf
= {
24 static struct conf_load conf_load
= {
25 .conf_fprintf
= &conf
,
31 const struct variable
*var
;
38 const struct function
*fun
;
44 static void oom(const char *msg
)
46 fprintf(stderr
, "pglobal: out of memory (%s)\n", msg
);
50 static struct extvar
*extvar__new(const struct variable
*var
,
53 struct extvar
*gvar
= malloc(sizeof(*gvar
));
59 gvar
->name
= variable__name(var
);
65 static struct extfun
*extfun__new(struct function
*fun
,
68 struct extfun
*gfun
= malloc(sizeof(*gfun
));
74 gfun
->name
= function__name(fun
);
80 static int extvar__compare(const void *a
, const void *b
)
82 const struct extvar
*ga
= a
, *gb
= b
;
83 return strcmp(ga
->name
, gb
->name
);
86 static int extfun__compare(const void *a
, const void *b
)
88 const struct extfun
*ga
= a
, *gb
= b
;
89 return strcmp(ga
->name
, gb
->name
);
92 static void extvar__add(const struct variable
*var
, const struct cu
*cu
)
94 struct extvar
**nodep
, *gvar
= extvar__new(var
, cu
);
97 nodep
= tsearch(gvar
, &tree
, extvar__compare
);
100 else if (*nodep
!= gvar
) {
101 if (gvar
->var
->declaration
) {
102 gvar
->next
= (*nodep
)->next
;
103 (*nodep
)->next
= gvar
;
112 static void extfun__add(struct function
*fun
, const struct cu
*cu
)
114 struct extfun
**nodep
, *gfun
= extfun__new(fun
, cu
);
117 nodep
= tsearch(gfun
, &tree
, extfun__compare
);
120 else if (*nodep
!= gfun
) {
121 gfun
->next
= (*nodep
)->next
;
122 (*nodep
)->next
= gfun
;
127 static int cu_extvar_iterator(struct cu
*cu
, void *cookie __maybe_unused
)
132 cu__for_each_variable(cu
, id
, pos
) {
133 struct variable
*var
= tag__variable(pos
);
135 extvar__add(var
, cu
);
140 static int cu_extfun_iterator(struct cu
*cu
, void *cookie __maybe_unused
)
142 struct function
*pos
;
145 cu__for_each_function(cu
, id
, pos
)
147 extfun__add(pos
, cu
);
151 static inline const struct extvar
*node__variable(const void *nodep
)
153 return *((const struct extvar
**)nodep
);
156 static inline const struct extfun
*node__function(const void *nodep
)
158 return *((const struct extfun
**)nodep
);
161 static inline struct tag
*extvar__tag(const struct extvar
*gvar
)
163 return (struct tag
*)gvar
->var
;
166 static inline struct tag
*extfun__tag(const struct extfun
*gfun
)
168 return (struct tag
*)gfun
->fun
;
171 static void declaration_action__walk(const void *nodep
, const VISIT which
,
172 const int depth __maybe_unused
)
176 const struct extvar
*pos
, *gvar
= NULL
;
182 gvar
= node__variable(nodep
);
187 gvar
= node__variable(nodep
);
194 tag
= extvar__tag(gvar
);
196 tag__fprintf(tag
, gvar
->cu
, NULL
, stdout
);
198 for (pos
= gvar
->next
; pos
; pos
= pos
->next
)
201 printf("; /* %u */\n\n", count
);
204 static void function_action__walk(const void *nodep
, const VISIT which
,
205 const int depth __maybe_unused
)
208 const struct extfun
*gfun
= NULL
;
214 gfun
= node__function(nodep
);
219 gfun
= node__function(nodep
);
226 tag
= extfun__tag(gfun
);
228 tag__fprintf(tag
, gfun
->cu
, NULL
, stdout
);
230 fputs("\n\n", stdout
);
233 static void free_node(void *nodep
)
239 /* Name and version of program. */
240 ARGP_PROGRAM_VERSION_HOOK_DEF
= dwarves_print_version
;
242 static const struct argp_option pglobal__options
[] = {
246 .doc
= "show global variables",
251 .doc
= "show global functions",
254 .name
= "format_path",
256 .arg
= "FORMAT_LIST",
257 .doc
= "List of debugging formats to try"
269 static int walk_var
, walk_fun
;
271 static error_t
pglobal__options_parser(int key
, char *arg __maybe_unused
,
272 struct argp_state
*state
)
276 if (state
->child_inputs
!= NULL
)
277 state
->child_inputs
[0] = state
->input
;
279 case 'v': walk_var
= 1; break;
280 case 'f': walk_fun
= 1; break;
281 case 'V': verbose
= 1; break;
282 case 'F': conf_load
.format_path
= arg
; break;
283 default: return ARGP_ERR_UNKNOWN
;
288 static const char pglobal__args_doc
[] = "FILE";
290 static struct argp pglobal__argp
= {
291 .options
= pglobal__options
,
292 .parser
= pglobal__options_parser
,
293 .args_doc
= pglobal__args_doc
,
296 int main(int argc
, char *argv
[])
298 int err
, remaining
, rc
= EXIT_FAILURE
;
300 if (argp_parse(&pglobal__argp
, argc
, argv
, 0, &remaining
, NULL
) ||
302 argp_help(&pglobal__argp
, stderr
, ARGP_HELP_SEE
, argv
[0]);
306 if (dwarves__init()) {
307 fputs("pglobal: insufficient memory\n", stderr
);
311 dwarves__resolve_cacheline_size(&conf_load
, 0);
313 struct cus
*cus
= cus__new();
315 fputs("pglobal: insufficient memory\n", stderr
);
316 goto out_dwarves_exit
;
319 err
= cus__load_files(cus
, &conf_load
, argv
+ remaining
);
321 cus__fprintf_load_files_err(cus
, "pglobal", argv
+ remaining
, err
, stderr
);
326 cus__for_each_cu(cus
, cu_extvar_iterator
, NULL
, NULL
);
327 twalk(tree
, declaration_action__walk
);
328 } else if (walk_fun
) {
329 cus__for_each_cu(cus
, cu_extfun_iterator
, NULL
, NULL
);
330 twalk(tree
, function_action__walk
);
333 tdestroy(tree
, free_node
);