Commit 06b8b036 authored by Sami Tolvanen's avatar Sami Tolvanen Committed by Masahiro Yamada
Browse files

gendwarfksyms: Expand type modifiers and typedefs



Add support for expanding DWARF type modifiers, such as pointers,
const values etc., and typedefs. These types all have DW_AT_type
attribute pointing to the underlying type, and thus produce similar
output.

Also add linebreaks and indentation to debugging output to make it
more readable.

Signed-off-by: default avatarSami Tolvanen <samitolvanen@google.com>
Reviewed-by: default avatarPetr Pavlu <petr.pavlu@suse.com>
Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
parent 0c1c7627
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -130,6 +130,18 @@ void die_map_add_string(struct die *cd, const char *str)
	df->type = FRAGMENT_STRING;
}

void die_map_add_linebreak(struct die *cd, int linebreak)
{
	struct die_fragment *df;

	if (!cd)
		return;

	df = append_item(cd);
	df->data.linebreak = linebreak;
	df->type = FRAGMENT_LINEBREAK;
}

void die_map_add_die(struct die *cd, struct die *child)
{
	struct die_fragment *df;
+67 −0
Original line number Diff line number Diff line
@@ -7,6 +7,17 @@
#include <stdarg.h>
#include "gendwarfksyms.h"

static bool do_linebreak;
static int indentation_level;

/* Line breaks and indentation for pretty-printing */
static void process_linebreak(struct die *cache, int n)
{
	indentation_level += n;
	do_linebreak = true;
	die_map_add_linebreak(cache, n);
}

#define DEFINE_GET_ATTR(attr, type)                                    \
	static bool get_##attr##_attr(Dwarf_Die *die, unsigned int id, \
				      type *value)                     \
@@ -76,6 +87,12 @@ static void process(struct die *cache, const char *s)
{
	s = s ?: "<null>";

	if (dump_dies && do_linebreak) {
		fputs("\n", stderr);
		for (int i = 0; i < indentation_level; i++)
			fputs("  ", stderr);
		do_linebreak = false;
	}
	if (dump_dies)
		fputs(s, stderr);

@@ -239,6 +256,40 @@ static void process_type_attr(struct state *state, struct die *cache,
	process(cache, "base_type void");
}

/* Container types with DW_AT_type */
static void __process_type(struct state *state, struct die *cache,
			   Dwarf_Die *die, const char *type)
{
	process(cache, type);
	process_fqn(cache, die);
	process(cache, " {");
	process_linebreak(cache, 1);
	process_type_attr(state, cache, die);
	process_linebreak(cache, -1);
	process(cache, "}");
	process_byte_size_attr(cache, die);
	process_alignment_attr(cache, die);
}

#define DEFINE_PROCESS_TYPE(type)                                            \
	static void process_##type##_type(struct state *state,               \
					  struct die *cache, Dwarf_Die *die) \
	{                                                                    \
		__process_type(state, cache, die, #type "_type");            \
	}

DEFINE_PROCESS_TYPE(atomic)
DEFINE_PROCESS_TYPE(const)
DEFINE_PROCESS_TYPE(immutable)
DEFINE_PROCESS_TYPE(packed)
DEFINE_PROCESS_TYPE(pointer)
DEFINE_PROCESS_TYPE(reference)
DEFINE_PROCESS_TYPE(restrict)
DEFINE_PROCESS_TYPE(rvalue_reference)
DEFINE_PROCESS_TYPE(shared)
DEFINE_PROCESS_TYPE(volatile)
DEFINE_PROCESS_TYPE(typedef)

static void process_base_type(struct state *state, struct die *cache,
			      Dwarf_Die *die)
{
@@ -260,6 +311,9 @@ static void process_cached(struct state *state, struct die *cache,
		case FRAGMENT_STRING:
			process(NULL, df->data.str);
			break;
		case FRAGMENT_LINEBREAK:
			process_linebreak(NULL, df->data.linebreak);
			break;
		case FRAGMENT_DIE:
			if (!dwarf_die_addr_die(dwarf_cu_getdwarf(die->cu),
						(void *)df->data.addr, &child))
@@ -295,7 +349,20 @@ static int process_type(struct state *state, struct die *parent, Dwarf_Die *die)
	}

	switch (tag) {
	/* Type modifiers */
	PROCESS_TYPE(atomic)
	PROCESS_TYPE(const)
	PROCESS_TYPE(immutable)
	PROCESS_TYPE(packed)
	PROCESS_TYPE(pointer)
	PROCESS_TYPE(reference)
	PROCESS_TYPE(restrict)
	PROCESS_TYPE(rvalue_reference)
	PROCESS_TYPE(shared)
	PROCESS_TYPE(volatile)
	/* Other types */
	PROCESS_TYPE(base)
	PROCESS_TYPE(typedef)
	default:
		debug("unimplemented type: %x", tag);
		break;
+5 −0
Original line number Diff line number Diff line
@@ -59,6 +59,9 @@ extern int dump_dies;
/* Error == negative values */
#define checkp(expr) __check(expr, __res < 0)

/* Consistent aliases (DW_TAG_<type>_type) for DWARF tags */
#define DW_TAG_typedef_type DW_TAG_typedef

/*
 * symbols.c
 */
@@ -100,6 +103,7 @@ enum die_state {
enum die_fragment_type {
	FRAGMENT_EMPTY,
	FRAGMENT_STRING,
	FRAGMENT_LINEBREAK,
	FRAGMENT_DIE
};

@@ -107,6 +111,7 @@ struct die_fragment {
	enum die_fragment_type type;
	union {
		char *str;
		int linebreak;
		uintptr_t addr;
	} data;
	struct list_head list;