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: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
This commit is contained in:
Sami Tolvanen
2025-01-03 20:45:27 +00:00
committed by Masahiro Yamada
parent 0c1c76274e
commit 06b8b036ab
3 changed files with 84 additions and 0 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;