Re: [PATCH dwarves v2] pahole: Inject kfunc decl tags into BTF

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

 



On Wed, Jan 10, 2024 at 06:14:25PM -0700, Daniel Xu wrote:

SNIP

> +
> +static int btf_encoder__tag_kfuncs(struct btf_encoder *encoder)
> +{
> +	const char *filename = encoder->filename;
> +	Elf_Scn *symscn = NULL;
> +	int symbols_shndx = -1;
> +	int fd = -1, err = -1;
> +	int idlist_shndx = -1;
> +	Elf_Scn *scn = NULL;
> +	size_t idlist_addr;
> +	Elf_Data *symbols;
> +	Elf_Data *idlist;
> +	size_t strtabidx;
> +	Elf *elf = NULL;
> +	int set_cnt = 0;
> +	GElf_Shdr shdr;
> +	size_t strndx;
> +	char *secname;
> +	int nr_syms;
> +	int i = 0;

smooth ;-)

SNIP

> +
> +	nr_syms = shdr.sh_size / shdr.sh_entsize;
> +	for (i = 0; i < nr_syms; i++) {
> +		char *kfunc, *name;
> +		int new_set_cnt;
> +		GElf_Sym sym;
> +		int err;
> +
> +		if (!gelf_getsym(symbols, i, &sym)) {
> +			elf_error("Failed to get ELF symbol(%d)", i);
> +			goto out;
> +		}
> +
> +		if (sym.st_shndx != idlist_shndx)
> +			continue;
> +
> +		name = elf_strptr(elf, strtabidx, sym.st_name);
> +		new_set_cnt = get_kfunc_set_cnt(&sym, name, idlist, idlist_addr);
> +		if (new_set_cnt < 0) {
> +			err = new_set_cnt;
> +			goto out;
> +		} else if (new_set_cnt) {
> +			if (set_cnt)
> +				fprintf(stderr, "%s: warning: overlapping set8 '%s'\n",
> +					__func__, name);
> +			set_cnt = new_set_cnt;
> +			continue;
> +		}
> +
> +		if (!set_cnt)
> +			continue;
> +		set_cnt--;
> +
> +		kfunc = get_kfunc_name(name);
> +		if (!kfunc)
> +			continue;
> +
> +		err = btf_encoder__tag_kfunc(encoder, kfunc);

are .BTF_ids records guaranteed to be sorted by address? so we are
sure that the set will be followed by its records?

I thought we'd need to find size for each set and then check each
.BTF_ids record if it belongs to the set

jirka


> +		if (err) {
> +			fprintf(stderr, "%s: failed to tag kfunc '%s'\n", __func__, kfunc);
> +			free(kfunc);
> +			goto out;
> +		}
> +		free(kfunc);
> +	}
> +
> +	err = 0;
> +out:
> +	if (elf)
> +		elf_end(elf);
> +	if (fd != -1)
> +		close(fd);
> +	return err;
> +}
> +
>  int btf_encoder__encode(struct btf_encoder *encoder)
>  {
>  	int err;
> @@ -1366,6 +1681,14 @@ int btf_encoder__encode(struct btf_encoder *encoder)
>  	if (btf__type_cnt(encoder->btf) == 1)
>  		return 0;
>  
> +	/* Note vmlinux may already contain btf_decl_tag's for kfuncs. So
> +	 * take care to call this before btf_dedup().
> +	 */
> +	if (btf_encoder__tag_kfuncs(encoder)) {
> +		fprintf(stderr, "%s: failed to tag kfuncs!\n", __func__);
> +		return -1;
> +	}
> +
>  	if (btf__dedup(encoder->btf, NULL)) {
>  		fprintf(stderr, "%s: btf__dedup failed!\n", __func__);
>  		return -1;
> @@ -1712,6 +2035,7 @@ void btf_encoder__delete(struct btf_encoder *encoder)
>  
>  	btf_encoders__delete(encoder);
>  	__gobuffer__delete(&encoder->percpu_secinfo);
> +	__gobuffer__delete(&encoder->btf_funcs);
>  	zfree(&encoder->filename);
>  	btf__free(encoder->btf);
>  	encoder->btf = NULL;
> -- 
> 2.42.1
> 




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux