Add the --encode_all_btf_vars option, which conflicts with --skip_encoding_btf_vars, and will enable encoding all variables which have a corresponding STT_OBJECT match in the ELF symbol table. Rework the btf_encoder_new() signature to include a single enum to specify which kinds of variables are allowed, and add the necessary logic to select variables. Signed-off-by: Stephen Brennan <stephen.s.brennan@xxxxxxxxxx> --- btf_encoder.c | 22 +++++++++++++--------- btf_encoder.h | 8 +++++++- man-pages/pahole.1 | 6 +++++- pahole.c | 31 +++++++++++++++++++++++++------ 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/btf_encoder.c b/btf_encoder.c index 1804500..eabc8d2 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -61,7 +61,6 @@ struct btf_encoder { struct elf_symtab *symtab; bool has_index_type, need_index_type, - skip_encoding_vars, raw_output, verbose, force, @@ -70,6 +69,7 @@ struct btf_encoder { uint32_t array_index_id; struct elf_secinfo secinfo[MAX_ELF_SEC_CNT]; size_t seccnt; + enum btf_var_option encode_vars; struct { struct var_info *vars; int var_cnt; @@ -1198,24 +1198,25 @@ static int btf_encoder__collect_var(struct btf_encoder *encoder, GElf_Sym *sym, return 0; } -static int btf_encoder__collect_symbols(struct btf_encoder *encoder, bool collect_percpu_vars) +static int btf_encoder__collect_symbols(struct btf_encoder *encoder) { uint32_t sym_sec_idx; uint32_t core_id; GElf_Sym sym; + bool collect_vars = (encoder->encode_vars != BTF_VAR_NONE); /* cache variables' addresses, preparing for searching in symtab. */ encoder->variables.var_cnt = 0; /* search within symtab for percpu variables */ elf_symtab__for_each_symbol_index(encoder->symtab, core_id, sym, sym_sec_idx) { - if (collect_percpu_vars && btf_encoder__collect_var(encoder, &sym, sym_sec_idx)) + if (collect_vars && btf_encoder__collect_var(encoder, &sym, sym_sec_idx)) return -1; if (btf_encoder__collect_function(encoder, &sym)) return -1; } - if (collect_percpu_vars) { + if (collect_vars) { if (encoder->variables.var_cnt) qsort(encoder->variables.vars, encoder->variables.var_cnt, sizeof(encoder->variables.vars[0]), var_cmp); @@ -1375,7 +1376,7 @@ out: return err; } -struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filename, struct btf *base_btf, bool skip_encoding_vars, bool force, bool gen_floats, bool verbose) +struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filename, struct btf *base_btf, enum btf_var_option vars, bool force, bool gen_floats, bool verbose) { struct btf_encoder *encoder = zalloc(sizeof(*encoder)); @@ -1391,11 +1392,11 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam encoder->force = force; encoder->gen_floats = gen_floats; - encoder->skip_encoding_vars = skip_encoding_vars; encoder->verbose = verbose; encoder->has_index_type = false; encoder->need_index_type = false; encoder->array_index_id = 0; + encoder->encode_vars = vars; GElf_Ehdr ehdr; @@ -1445,17 +1446,20 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam encoder->secinfo[shndx].addr = shdr.sh_addr; encoder->secinfo[shndx].sz = shdr.sh_size; encoder->secinfo[shndx].name = secname; + if (encoder->encode_vars == BTF_VAR_ALL) + encoder->secinfo[shndx].include = true; if (strcmp(secname, PERCPU_SECTION) == 0) { encoder->variables.percpu_shndx = shndx; - encoder->secinfo[shndx].include = true; + if (encoder->encode_vars != BTF_VAR_NONE) + encoder->secinfo[shndx].include = true; } } if (!encoder->variables.percpu_shndx && encoder->verbose) printf("%s: '%s' doesn't have '%s' section\n", __func__, cu->filename, PERCPU_SECTION); - if (btf_encoder__collect_symbols(encoder, !encoder->skip_encoding_vars)) + if (btf_encoder__collect_symbols(encoder)) goto out_delete; if (encoder->verbose) @@ -1615,7 +1619,7 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct co } } - if (!encoder->skip_encoding_vars) + if (encoder->encode_vars != BTF_VAR_NONE) err = btf_encoder__encode_cu_variables(encoder, cu, type_id_off); out: return err; diff --git a/btf_encoder.h b/btf_encoder.h index a65120c..e03c7cc 100644 --- a/btf_encoder.h +++ b/btf_encoder.h @@ -16,7 +16,13 @@ struct btf; struct cu; struct list_head; -struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filename, struct btf *base_btf, bool skip_encoding_vars, bool force, bool gen_floats, bool verbose); +enum btf_var_option { + BTF_VAR_NONE, + BTF_VAR_PERCPU, + BTF_VAR_ALL, +}; + +struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filename, struct btf *base_btf, enum btf_var_option vars, bool force, bool gen_floats, bool verbose); void btf_encoder__delete(struct btf_encoder *encoder); int btf_encoder__encode(struct btf_encoder *encoder); diff --git a/man-pages/pahole.1 b/man-pages/pahole.1 index bb88e2f..d21af0a 100644 --- a/man-pages/pahole.1 +++ b/man-pages/pahole.1 @@ -207,7 +207,11 @@ the debugging information. .TP .B \-\-skip_encoding_btf_vars -Do not encode VARs in BTF. +.TQ +.B \-\-encode_all_btf_vars +By default, VARs are encoded only for percpu variables. These options allow +to skip encoding them, or to encode all variables regardless of whether they are +percpu. These options are mutually exclusive. .TP .B \-\-skip_encoding_btf_decl_tag diff --git a/pahole.c b/pahole.c index e87d9a4..1f86ffb 100644 --- a/pahole.c +++ b/pahole.c @@ -4,6 +4,7 @@ Copyright (C) 2006 Mandriva Conectiva S.A. Copyright (C) 2006 Arnaldo Carvalho de Melo <acme@xxxxxxxxxxxx> Copyright (C) 2007- Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> + Copyright (c) 2022 Oracle and/or its affiliates. */ #include <argp.h> @@ -37,7 +38,7 @@ static bool ctf_encode; static bool sort_output; static bool need_resort; static bool first_obj_only; -static bool skip_encoding_btf_vars; +static enum btf_var_option encode_btf_vars = BTF_VAR_PERCPU; static bool btf_encode_force; static const char *base_btf_file; @@ -1221,6 +1222,7 @@ ARGP_PROGRAM_VERSION_HOOK_DEF = dwarves_print_version; #define ARGP_languages 335 #define ARGP_languages_exclude 336 #define ARGP_skip_encoding_btf_enum64 337 +#define ARGP_encode_all_btf_vars 338 static const struct argp_option pahole__options[] = { { @@ -1532,7 +1534,12 @@ static const struct argp_option pahole__options[] = { { .name = "skip_encoding_btf_vars", .key = ARGP_skip_encoding_btf_vars, - .doc = "Do not encode VARs in BTF." + .doc = "Do not encode any VARs in BTF (default: only percpu)." + }, + { + .name = "encode_all_btf_vars", + .key = ARGP_encode_all_btf_vars, + .doc = "Encode all VARs in BTF (default: only percpu)." }, { .name = "btf_encode_force", @@ -1757,8 +1764,6 @@ static error_t pahole__options_parser(int key, char *arg, conf.range = arg; break; case ARGP_header_type: conf.header_type = arg; break; - case ARGP_skip_encoding_btf_vars: - skip_encoding_btf_vars = true; break; case ARGP_btf_encode_force: btf_encode_force = true; break; case ARGP_btf_base: @@ -1795,6 +1800,20 @@ static error_t pahole__options_parser(int key, char *arg, languages.str = arg; break; case ARGP_skip_encoding_btf_enum64: conf_load.skip_encoding_btf_enum64 = true; break; + case ARGP_skip_encoding_btf_vars: + if (encode_btf_vars != BTF_VAR_PERCPU) { + fprintf(stderr, "error: --encode_all_btf_vars and --skip_encoding_btf_vars are mutually exclusive\n"); + return ARGP_HELP_SEE; + } + encode_btf_vars = BTF_VAR_NONE; + break; + case ARGP_encode_all_btf_vars: + if (encode_btf_vars != BTF_VAR_PERCPU) { + fprintf(stderr, "error: --encode_all_btf_vars and --skip_encoding_btf_vars are mutually exclusive\n"); + return ARGP_HELP_SEE; + } + encode_btf_vars = BTF_VAR_ALL; + break; default: return ARGP_ERR_UNKNOWN; } @@ -3034,7 +3053,7 @@ static enum load_steal_kind pahole_stealer(struct cu *cu, * And, it is used by the thread * create it. */ - btf_encoder = btf_encoder__new(cu, detached_btf_filename, conf_load->base_btf, skip_encoding_btf_vars, + btf_encoder = btf_encoder__new(cu, detached_btf_filename, conf_load->base_btf, encode_btf_vars, btf_encode_force, btf_gen_floats, global_verbose); if (btf_encoder && thr_data) { struct thread_data *thread = thr_data; @@ -3064,7 +3083,7 @@ static enum load_steal_kind pahole_stealer(struct cu *cu, thread->encoder = btf_encoder__new(cu, detached_btf_filename, NULL, - skip_encoding_btf_vars, + encode_btf_vars, btf_encode_force, btf_gen_floats, global_verbose); -- 2.34.1