The "artificial" flag corresponds directly to DW_AT_artificial, which indicates a compiler-generated variable (e.g. __func__) which shouldn't be included in the output. The "top_level" flag is intended to be a better proxy for global scoped variables. It indicates that a variable was a direct child of a compilation unit, rather than a child of a subroutine or lexical block. Currently, the DWARF loader examines the DWARF location expression, and if the location is found to be at a constant memory address (not stack, register, etc), then the variable is assumed to be globally scoped. However, this includes a variety of variables that aren't truly globally scoped: most commonly, static local variables of functions. Their locations may be static, but they're not globally accessible in any useful way. These flags will be used by the BTF encoder to select global variables. Signed-off-by: Stephen Brennan <stephen.s.brennan@xxxxxxxxxx> Reviewed-by: Alan Maguire <alan.maguire@xxxxxxxxxx> --- dwarf_loader.c | 12 +++++++----- dwarves.h | 2 ++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/dwarf_loader.c b/dwarf_loader.c index 065ed4d..d162214 100644 --- a/dwarf_loader.c +++ b/dwarf_loader.c @@ -730,7 +730,7 @@ const char *variable__scope_str(const struct variable *var) return "unknown"; } -static struct variable *variable__new(Dwarf_Die *die, struct cu *cu, struct conf_load *conf) +static struct variable *variable__new(Dwarf_Die *die, struct cu *cu, struct conf_load *conf, int top_level) { bool has_specification = dwarf_hasattr(die, DW_AT_specification); struct variable *var = tag__alloc(cu, sizeof(*var)); @@ -743,6 +743,8 @@ static struct variable *variable__new(Dwarf_Die *die, struct cu *cu, struct conf /* non-defining declaration of an object */ var->declaration = dwarf_hasattr(die, DW_AT_declaration); var->has_specification = has_specification; + var->artificial = dwarf_hasattr(die, DW_AT_artificial); + var->top_level = top_level; var->scope = VSCOPE_UNKNOWN; INIT_LIST_HEAD(&var->annots); var->ip.addr = 0; @@ -1767,9 +1769,9 @@ static struct tag *die__create_new_label(Dwarf_Die *die, return &label->ip.tag; } -static struct tag *die__create_new_variable(Dwarf_Die *die, struct cu *cu, struct conf_load *conf) +static struct tag *die__create_new_variable(Dwarf_Die *die, struct cu *cu, struct conf_load *conf, int top_level) { - struct variable *var = variable__new(die, cu, conf); + struct variable *var = variable__new(die, cu, conf, top_level); if (var == NULL || add_child_llvm_annotations(die, -1, conf, &var->annots)) return NULL; @@ -2243,7 +2245,7 @@ static int die__process_function(Dwarf_Die *die, struct ftype *ftype, tag = die__create_new_parameter(die, ftype, lexblock, cu, conf, param_idx++); break; case DW_TAG_variable: - tag = die__create_new_variable(die, cu, conf); + tag = die__create_new_variable(die, cu, conf, 0); if (tag == NULL) goto out_enomem; lexblock__add_variable(lexblock, tag__variable(tag)); @@ -2367,7 +2369,7 @@ static struct tag *__die__process_tag(Dwarf_Die *die, struct cu *cu, case DW_TAG_union_type: tag = die__create_new_union(die, cu, conf); break; case DW_TAG_variable: - tag = die__create_new_variable(die, cu, conf); break; + tag = die__create_new_variable(die, cu, conf, top_level); break; case DW_TAG_constant: // First seen in a Go CU tag = die__create_new_constant(die, cu, conf); break; default: diff --git a/dwarves.h b/dwarves.h index f2d3988..0fede91 100644 --- a/dwarves.h +++ b/dwarves.h @@ -848,6 +848,8 @@ struct variable { uint8_t external:1; uint8_t declaration:1; uint8_t has_specification:1; + uint8_t artificial:1; + uint8_t top_level:1; enum vscope scope; struct location location; struct hlist_node tool_hnode; -- 2.43.5