Re: [PATCH v3 dwarves 2/5] btf_encoder: introduce elf_functions struct type

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 16/10/2024 01:10, Ihor Solodrai wrote:
> Extract elf_functions struct type from btf_encoder.
> 
> Replace methods operating functions table in btf_encoder by methods
> operating on elf_functions:
> - btf_encoder__collect_function -> elf_functions__collect_function
> - btf_encoder__collect_symbols -> elf_functions__collect
> 
> Now these functions do not depend on btf_encoder being passed to them
> as a parameter.
> 
> Signed-off-by: Ihor Solodrai <ihor.solodrai@xxxxx>

a few small things, but

Reviewed-by: Alan Maguire <alan.maguire@xxxxxxxxxx>

> ---
>  btf_encoder.c | 122 +++++++++++++++++++++++++++-----------------------
>  1 file changed, 66 insertions(+), 56 deletions(-)
> 
> diff --git a/btf_encoder.c b/btf_encoder.c
> index 5954238..9c840fa 100644
> --- a/btf_encoder.c
> +++ b/btf_encoder.c
> @@ -102,6 +102,13 @@ struct elf_secinfo {
>  	struct gobuffer secinfo;
>  };
>  
> +struct elf_functions {
> +	struct elf_symtab *symtab;
> +	struct elf_function *entries;
> +	int cnt;
> +	int suffix_cnt; /* number of .isra, .part etc */
> +};
> +
>  /*
>   * cu: cu being processed.
>   */
> @@ -126,12 +133,7 @@ struct btf_encoder {
>  	struct elf_secinfo *secinfo;
>  	size_t             seccnt;
>  	int                encode_vars;
> -	struct {
> -		struct elf_function *entries;
> -		int		    allocated;
> -		int		    cnt;
> -		int		    suffix_cnt; /* number of .isra, .part etc */
> -	} functions;
> +	struct elf_functions functions;
>  };
>  
>  struct btf_func {
> @@ -1299,55 +1301,28 @@ static int functions_cmp(const void *_a, const void *_b)
>  	return strcmp(a->name, b->name);
>  }
>  
> -#ifndef max
> -#define max(x, y) ((x) < (y) ? (y) : (x))
> -#endif
> -
> -static void *reallocarray_grow(void *ptr, int *nmemb, size_t size)
> -{
> -	int new_nmemb = max(1000, *nmemb * 3 / 2);
> -	void *new = realloc(ptr, new_nmemb * size);
> -
> -	if (new)
> -		*nmemb = new_nmemb;
> -	return new;
> -}
> -
> -static int btf_encoder__collect_function(struct btf_encoder *encoder, GElf_Sym *sym)
> +static int elf_functions__collect_function(struct elf_functions *functions, GElf_Sym *sym)
>  {
> -	struct elf_function *new;
> +	struct elf_function *func;
>  	const char *name;
>  
>  	if (elf_sym__type(sym) != STT_FUNC)
>  		return 0;
> -	name = elf_sym__name(sym, encoder->symtab);
> +
> +	name = elf_sym__name(sym, functions->symtab);
>  	if (!name)
>  		return 0;
>  
> -	if (encoder->functions.cnt == encoder->functions.allocated) {
> -		new = reallocarray_grow(encoder->functions.entries,
> -					&encoder->functions.allocated,
> -					sizeof(*encoder->functions.entries));
> -		if (!new) {
> -			/*
> -			 * The cleanup - delete_functions is called
> -			 * in btf_encoder__encode_cu error path.
> -			 */
> -			return -1;
> -		}
> -		encoder->functions.entries = new;
> -	}
> -
> -	memset(&encoder->functions.entries[encoder->functions.cnt], 0,
> -	       sizeof(*new));
> -	encoder->functions.entries[encoder->functions.cnt].name = name;
> +	func = &functions->entries[functions->cnt];
> +	func->name = name;
>  	if (strchr(name, '.')) {
>  		const char *suffix = strchr(name, '.');
> -
> -		encoder->functions.suffix_cnt++;
> -		encoder->functions.entries[encoder->functions.cnt].prefixlen = suffix - name;
> +		functions->suffix_cnt++;
> +		func->prefixlen = suffix - name;
>  	}
> -	encoder->functions.cnt++;
> +
> +	functions->cnt++;
> +
>  	return 0;
>  }
>  
> @@ -2099,26 +2074,60 @@ int btf_encoder__encode(struct btf_encoder *encoder)
>  	return err;
>  }
>  
> -
> -static int btf_encoder__collect_symbols(struct btf_encoder *encoder)
> +static int elf_functions__collect(struct elf_functions *functions)
>  {
> -	uint32_t sym_sec_idx;
> +	uint32_t nr_symbols = elf_symtab__nr_symbols(functions->symtab);
> +	struct elf_function *tmp;
> +	Elf32_Word sym_sec_idx;
>  	uint32_t core_id;
>  	GElf_Sym sym;
> +	int err;
>  
> -	elf_symtab__for_each_symbol_index(encoder->symtab, core_id, sym, sym_sec_idx) {
> -		if (btf_encoder__collect_function(encoder, &sym))
> -			return -1;
> +	/* We know that number of functions is less than number of symbols,
> +	 * so we can overallocate temporarily.
> +	 */
> +	functions->entries = calloc(nr_symbols, sizeof(struct elf_function));

So in testing  we hit a case (a module) with no functions, I presume a
case with zero symbols is extremely unlikely, but maybe just in case,

if (nr_symbols == 0)
	goto out_free;

(we should probably just initialize int err = 0; above)

> +	if (!functions->entries) {
> +		fprintf(stderr, "could not allocate memory for elf_functions table\n");
> +		err = -ENOMEM;
> +		goto out_free;
> +	}
> +
> +	functions->cnt = 0;
> +	elf_symtab__for_each_symbol_index(functions->symtab, core_id, sym, sym_sec_idx) {
> +		if (elf_functions__collect_function(functions, &sym)) {
> +			err = -1;
> +			goto out_free;
> +		}
>  	}
>  
> -	if (encoder->functions.cnt) {
> -		qsort(encoder->functions.entries, encoder->functions.cnt, sizeof(encoder->functions.entries[0]),
> +	if (functions->cnt) {
> +		qsort(functions->entries,
> +		      functions->cnt,
> +		      sizeof(functions->entries[0]),
>  		      functions_cmp);
> -		if (encoder->verbose)
> -			printf("Found %d functions!\n", encoder->functions.cnt);
> +	} else {
> +		err = 0;

nit: as noted above start with err = 0 and we can just goto out_free.

> +		goto out_free;
> +	}
> +
> +	/* Reallocate to the exact size */
> +	tmp = realloc(functions->entries, functions->cnt * sizeof(struct elf_function));
> +	if (tmp) {
> +		functions->entries = tmp;
> +	} else {
> +		fprintf(stderr, "could not reallocate memory for elf_functions table\n");
> +		err = -ENOMEM;
> +		goto out_free;
>  	}
>  
>  	return 0;
> +
> +out_free:
> +	free(functions->entries);
> +	functions->entries = NULL;
> +	functions->cnt = 0;
> +	return err;
>  }
>  
>  static bool ftype__has_arg_names(const struct ftype *ftype)
> @@ -2377,6 +2386,7 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam
>  				printf("%s: '%s' doesn't have symtab.\n", __func__, cu->filename);
>  			goto out;
>  		}
> +		encoder->functions.symtab = encoder->symtab;
>  

nit: unless there's a reason otherwise, this assignment seems to more
naturally belong in elf_functions__collect().

>  		/* index the ELF sections for later lookup */
>  
> @@ -2415,7 +2425,7 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam
>  		if (!found_percpu && encoder->verbose)
>  			printf("%s: '%s' doesn't have '%s' section\n", __func__, cu->filename, PERCPU_SECTION);
>  
> -		if (btf_encoder__collect_symbols(encoder))
> +		if (elf_functions__collect(&encoder->functions))
>  			goto out_delete;
>  
>  		if (encoder->verbose)
> @@ -2456,7 +2466,7 @@ void btf_encoder__delete(struct btf_encoder *encoder)
>  
>  	for (i = 0; i < encoder->functions.cnt; i++)
>  		btf_encoder__delete_func(&encoder->functions.entries[i]);
> -	encoder->functions.allocated = encoder->functions.cnt = 0;
> +	encoder->functions.cnt = 0;
>  	free(encoder->functions.entries);
>  	encoder->functions.entries = NULL;
>  





[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux