@@ -65,7 +65,6 @@ struct btf_encoder {
struct elf_symtab *symtab;
bool has_index_type,
need_index_type,
- skip_encoding_vars,
raw_output,
verbose,
force,
@@ -74,6 +73,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;
@@ -1247,24 +1247,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);
@@ -1425,7 +1426,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));
@@ -1441,11 +1442,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;
@@ -1495,17 +1496,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)
@@ -1671,7 +1675,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, type_id_off);
out:
encoder->cu = NULL;
@@ -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);
@@ -215,7 +215,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
@@ -37,7 +37,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;
@@ -1222,6 +1222,7 @@ ARGP_PROGRAM_VERSION_HOOK_DEF = dwarves_print_version;
#define ARGP_languages_exclude 336
#define ARGP_skip_encoding_btf_enum64 337
#define ARGP_skip_emitting_atomic_typedefs 338
+#define ARGP_encode_all_btf_vars 339
static const struct argp_option pahole__options[] = {
{
@@ -1533,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",
@@ -1763,8 +1769,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:
@@ -1803,6 +1807,20 @@ static error_t pahole__options_parser(int key, char *arg,
conf_load.skip_encoding_btf_enum64 = true; break;
case ARGP_skip_emitting_atomic_typedefs:
conf.skip_emitting_atomic_typedefs = 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;
}
@@ -3037,7 +3055,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;
@@ -3067,7 +3085,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);
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@oracle.com> --- btf_encoder.c | 22 +++++++++++++--------- btf_encoder.h | 8 +++++++- man-pages/pahole.1 | 6 +++++- pahole.c | 30 ++++++++++++++++++++++++------ 4 files changed, 49 insertions(+), 17 deletions(-)