Introduce a global elf_functions_list variable in btf_encoder.c that contains an elf_functions per ELF. An elf_functions structure is allocated and filled out by btf_encoder__pre_cus__load_module hook, and disposed after btf_encoder__encode is done. At this point btf_encoders don't use shared elf_functions yet, but it is built before encoders are initialized. Signed-off-by: Ihor Solodrai <ihor.solodrai@xxxxx> --- btf_encoder.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ btf_encoder.h | 2 ++ pahole.c | 3 ++ 3 files changed, 81 insertions(+) diff --git a/btf_encoder.c b/btf_encoder.c index 8abca7f..9e05b56 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -103,6 +103,8 @@ struct elf_secinfo { }; struct elf_functions { + struct list_head node; // for elf_functions_list + Elf *elf; // source ELF struct elf_symtab *symtab; struct elf_function *entries; int cnt; @@ -147,6 +149,72 @@ struct btf_kfunc_set_range { uint64_t end; }; + +// In principle, multiple ELFs can be processed in one pahole run, +// so we have to store elf_functions table per ELF. +// An element is added to the list on btf_encoder__pre_cus__load_module, +// and removed after btf_encoder__encode is done. +static LIST_HEAD(elf_functions_list); + +static struct elf_functions *elf_functions__get(Elf *elf) +{ + struct list_head *pos; + + list_for_each(pos, &elf_functions_list) { + struct elf_functions *funcs = list_entry(pos, struct elf_functions, node); + + if (funcs->elf == elf) + return funcs; + } + return NULL; +} + +static inline void elf_functions__delete(struct elf_functions *funcs) +{ + free(funcs->entries); + elf_symtab__delete(funcs->symtab); + list_del(&funcs->node); + free(funcs); +} + +static int elf_functions__collect(struct elf_functions *functions); + +static struct elf_functions *elf_functions__new(Elf *elf) +{ + struct elf_functions *funcs = calloc(1, sizeof(*funcs)); + + if (!funcs) + return NULL; + funcs->elf = elf; + + funcs->symtab = elf_symtab__new(NULL, elf); + if (!funcs->symtab) + goto out_error; + + int err = elf_functions__collect(funcs); + + if (err) + goto out_error; + + list_add_tail(&funcs->node, &elf_functions_list); + return funcs; + +out_error: + elf_functions__delete(funcs); + return NULL; +} + +int btf_encoder__pre_cus__load_module(struct process_dwflmod_parms *parms, Dwfl_Module *mod, Dwarf *dw, Elf *elf) +{ + struct elf_functions *funcs = elf_functions__new(elf); + + if (!funcs) + return -1; + + return 0; +} + + static LIST_HEAD(encoders); static pthread_mutex_t encoders__lock = PTHREAD_MUTEX_INITIALIZER; @@ -2071,6 +2139,13 @@ int btf_encoder__encode(struct btf_encoder *encoder) #endif err = btf_encoder__write_elf(encoder, encoder->btf, BTF_ELF_SEC); } + + // TODO: after moving encoders to shared elf_functions, + // replace elf_functions__get(encoder->functions.elf) here + // with encoder->functions + // The pointer to shared elf_functions will be set in btf_encoder__new + elf_functions__delete(elf_functions__get(encoder->functions.elf)); + return err; } @@ -2369,6 +2444,7 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam goto out; } encoder->functions.symtab = encoder->symtab; + encoder->functions.elf = cu->elf; /* index the ELF sections for later lookup */ diff --git a/btf_encoder.h b/btf_encoder.h index 824963b..7bfc994 100644 --- a/btf_encoder.h +++ b/btf_encoder.h @@ -34,4 +34,6 @@ struct btf *btf_encoder__btf(struct btf_encoder *encoder); int btf_encoder__add_encoder(struct btf_encoder *encoder, struct btf_encoder *other); +int btf_encoder__pre_cus__load_module(struct process_dwflmod_parms *parms, Dwfl_Module *mod, Dwarf *dw, Elf *elf); + #endif /* _BTF_ENCODER_H_ */ diff --git a/pahole.c b/pahole.c index b9e97ef..0ff6bc2 100644 --- a/pahole.c +++ b/pahole.c @@ -3814,6 +3814,9 @@ int main(int argc, char *argv[]) conf_load.threads_collect = pahole_threads_collect; } + if (btf_encode) + conf_load.pre_cus__load_module = btf_encoder__pre_cus__load_module; + // Make 'pahole --header type < file' a shorter form of 'pahole -C type --count 1 < file' if (conf.header_type && !class_name && prettify_input) { conf.count = 1; -- 2.43.0