Blame pdwtags.c

Packit b92951
/*
Packit b92951
  SPDX-License-Identifier: GPL-2.0-only
Packit b92951
Packit b92951
  Copyright (C) 2007-2016 Arnaldo Carvalho de Melo <acme@kernel.org>
Packit b92951
*/
Packit b92951
Packit b92951
#include <argp.h>
Packit b92951
#include <stdio.h>
Packit b92951
#include <stdlib.h>
Packit b92951
#include <malloc.h>
Packit b92951
Packit b92951
#include "dwarves.h"
Packit b92951
#include "dutil.h"
Packit b92951
Packit b92951
static struct conf_fprintf conf = {
Packit b92951
	.emit_stats	= 1,
Packit b92951
};
Packit b92951
Packit b92951
static void emit_tag(struct tag *tag, uint32_t tag_id, struct cu *cu)
Packit b92951
{
Packit b92951
	printf("/* %d */\n", tag_id);
Packit b92951
Packit b92951
	if (tag__is_struct(tag))
Packit b92951
		class__find_holes(tag__class(tag));
Packit b92951
Packit b92951
	if (tag->tag == DW_TAG_base_type) {
Packit b92951
		char bf[64];
Packit b92951
		const char *name = base_type__name(tag__base_type(tag), cu,
Packit b92951
						   bf, sizeof(bf));
Packit b92951
Packit b92951
		if (name == NULL)
Packit b92951
			printf("anonymous base_type\n");
Packit b92951
		else
Packit b92951
			puts(name);
Packit b92951
	} else if (tag__is_pointer(tag))
Packit b92951
		printf(" /* pointer to %lld */\n", (unsigned long long)tag->type);
Packit b92951
	else
Packit b92951
		tag__fprintf(tag, cu, &conf, stdout);
Packit b92951
Packit b92951
	printf(" /* size: %zd */\n\n", tag__size(tag, cu));
Packit b92951
}
Packit b92951
Packit b92951
static int cu__emit_tags(struct cu *cu)
Packit b92951
{
Packit b92951
	uint32_t i;
Packit b92951
	struct tag *tag;
Packit b92951
Packit b92951
	puts("/* Types: */\n");
Packit b92951
	cu__for_each_type(cu, i, tag)
Packit b92951
		emit_tag(tag, i, cu);
Packit b92951
Packit b92951
	puts("/* Functions: */\n");
Packit b92951
	conf.no_semicolon = true;
Packit b92951
	struct function *function;
Packit b92951
	cu__for_each_function(cu, i, function) {
Packit b92951
		tag__fprintf(function__tag(function), cu, &conf, stdout);
Packit b92951
		putchar('\n');
Packit b92951
		lexblock__fprintf(&function->lexblock, cu, function, 0,
Packit b92951
				  &conf, stdout);
Packit b92951
		printf(" /* size: %zd */\n\n",
Packit b92951
		       tag__size(function__tag(function), cu));
Packit b92951
	}
Packit b92951
	conf.no_semicolon = false;
Packit b92951
Packit b92951
	puts("\n\n/* Variables: */\n");
Packit b92951
	cu__for_each_variable(cu, i, tag) {
Packit b92951
		tag__fprintf(tag, cu, NULL, stdout);
Packit b92951
		printf(" /* size: %zd */\n\n", tag__size(tag, cu));
Packit b92951
	}
Packit b92951
Packit b92951
Packit b92951
	return 0;
Packit b92951
}
Packit b92951
Packit b92951
static enum load_steal_kind pdwtags_stealer(struct cu *cu,
Packit b92951
					    struct conf_load *conf_load __unused)
Packit b92951
{
Packit b92951
	cu__emit_tags(cu);
Packit b92951
	return LSK__DELETE;
Packit b92951
}
Packit b92951
Packit b92951
static struct conf_load pdwtags_conf_load = {
Packit b92951
	.steal = pdwtags_stealer,
Packit b92951
	.conf_fprintf = &conf,
Packit b92951
};
Packit b92951
Packit b92951
/* Name and version of program.  */
Packit b92951
ARGP_PROGRAM_VERSION_HOOK_DEF = dwarves_print_version;
Packit b92951
Packit b92951
static const struct argp_option pdwtags__options[] = {
Packit b92951
	{
Packit b92951
		.name = "format_path",
Packit b92951
		.key  = 'F',
Packit b92951
		.arg  = "FORMAT_LIST",
Packit b92951
		.doc  = "List of debugging formats to try"
Packit b92951
	},
Packit b92951
	{
Packit b92951
		.key  = 'V',
Packit b92951
		.name = "verbose",
Packit b92951
		.doc  = "show details",
Packit b92951
	},
Packit b92951
	{
Packit b92951
		.name = NULL,
Packit b92951
	}
Packit b92951
};
Packit b92951
Packit b92951
static error_t pdwtags__options_parser(int key, char *arg __unused,
Packit b92951
				      struct argp_state *state)
Packit b92951
{
Packit b92951
	switch (key) {
Packit b92951
	case ARGP_KEY_INIT:
Packit b92951
		if (state->child_inputs != NULL)
Packit b92951
			state->child_inputs[0] = state->input;
Packit b92951
		break;
Packit b92951
	case 'F': pdwtags_conf_load.format_path = arg;	break;
Packit b92951
	case 'V': conf.show_decl_info = 1;		break;
Packit b92951
	default:  return ARGP_ERR_UNKNOWN;
Packit b92951
	}
Packit b92951
	return 0;
Packit b92951
}
Packit b92951
Packit b92951
static const char pdwtags__args_doc[] = "FILE";
Packit b92951
Packit b92951
static struct argp pdwtags__argp = {
Packit b92951
	.options  = pdwtags__options,
Packit b92951
	.parser	  = pdwtags__options_parser,
Packit b92951
	.args_doc = pdwtags__args_doc,
Packit b92951
};
Packit b92951
Packit b92951
int main(int argc, char *argv[])
Packit b92951
{
Packit b92951
	int remaining, rc = EXIT_FAILURE, err;
Packit b92951
	struct cus *cus = cus__new();
Packit b92951
Packit b92951
	if (dwarves__init(0) || cus == NULL) {
Packit b92951
		fputs("pwdtags: insufficient memory\n", stderr);
Packit b92951
		goto out;
Packit b92951
	}
Packit b92951
Packit b92951
	if (argp_parse(&pdwtags__argp, argc, argv, 0, &remaining, NULL) ||
Packit b92951
	    remaining == argc) {
Packit b92951
                argp_help(&pdwtags__argp, stderr, ARGP_HELP_SEE, argv[0]);
Packit b92951
                goto out;
Packit b92951
	}
Packit b92951
Packit b92951
	err = cus__load_files(cus, &pdwtags_conf_load, argv + remaining);
Packit b92951
	if (err == 0) {
Packit b92951
		rc = EXIT_SUCCESS;
Packit b92951
		goto out;
Packit b92951
	}
Packit b92951
Packit b92951
	cus__fprintf_load_files_err(cus, "pdwtags", argv + remaining, err, stderr);
Packit b92951
out:
Packit b92951
	cus__delete(cus);
Packit b92951
	dwarves__exit();
Packit b92951
	return rc;
Packit b92951
}