mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 12:21:22 -05:00
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:
committed by
Masahiro Yamada
parent
0c1c76274e
commit
06b8b036ab
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user