Dwarves Archive on lore.kernel.org
 help / color / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Andrii Nakryiko <andriin@fb.com>
Cc: dwarves@vger.kernel.org, bpf@vger.kernel.org
Subject: Re: [PATCH dwarves 04/11] btf_loader: use libbpf to load BTF
Date: Thu, 8 Oct 2020 15:06:51 -0300
Message-ID: <20201008180651.GD246083@kernel.org> (raw)
In-Reply-To: <20200930042742.2525310-5-andriin@fb.com>

Em Tue, Sep 29, 2020 at 09:27:35PM -0700, Andrii Nakryiko escreveu:
> Switch BTF loading to completely use libbpf's own struct btf and related APIs.
> BTF encoding is still happening with pahole's own code, so these two code
> paths are not sharing anything now. String fetching is happening based on
> whether btfe->strings were set to non-NULL pointer by btf_encoder.
 
This patch is not applying, since there was a fix in the btf_loader.c
file where lexblocks (DWARF concept) wasn't being initialized and then
some other tool was segfaulting when trying to traverse an uninitialized
list.

I tried applying this patch by hand, but it seems it needs some
massaging before I can use plain vim on it:

diff --git a/btf_loader.c b/btf_loader.c
index 9db76957a7e5..c31ee61060f1 100644
--- a/btf_loader.c
+++ b/btf_loader.c
@@ -46,21 +46,17 @@ static void *tag__alloc(const size_t size)
 }
=20
 static int btf_elf__load_ftype(struct btf_elf *btfe, struct ftype *proto=
, uint32_t tag,
-                              uint32_t type, uint16_t vlen, struct btf_param *args, uint32_t=
 id)
+                              const struct btf_type *tp, uint32_t id)
 {
-       int i;
+       const struct btf_param *param =3D btf_params(tp);
+       int i, vlen =3D btf_vlen(tp);
=20
        proto->tag.tag  =3D tag;
-       proto->tag.type =3D type;
+       proto->tag.type =3D tp->type;
        INIT_LIST_HEAD(&proto->parms);
=20
-       for (i =3D 0; i < vlen; ++i) {


Can you please check?

The first three patches are already applied an in master, both at
kernel.org and its mirror at github.com.

- Arnaldo

> Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> ---
>  btf_loader.c | 244 +++++++++++++++++++--------------------------------
>  libbtf.c     | 116 +++++-------------------
>  libbtf.h     |  11 +--
>  3 files changed, 113 insertions(+), 258 deletions(-)
> 
> diff --git a/btf_loader.c b/btf_loader.c
> index 9db76957a7e5..c31ee61060f1 100644
> --- a/btf_loader.c
> +++ b/btf_loader.c
> @@ -46,21 +46,17 @@ static void *tag__alloc(const size_t size)
>  }
>  
>  static int btf_elf__load_ftype(struct btf_elf *btfe, struct ftype *proto, uint32_t tag,
> -			       uint32_t type, uint16_t vlen, struct btf_param *args, uint32_t id)
> +			       const struct btf_type *tp, uint32_t id)
>  {
> -	int i;
> +	const struct btf_param *param = btf_params(tp);
> +	int i, vlen = btf_vlen(tp);
>  
>  	proto->tag.tag	= tag;
> -	proto->tag.type = type;
> +	proto->tag.type = tp->type;
>  	INIT_LIST_HEAD(&proto->parms);
>  
> -	for (i = 0; i < vlen; ++i) {
> -		struct btf_param param = {
> -		       .name_off = btf_elf__get32(btfe, &args[i].name_off),
> -		       .type	 = btf_elf__get32(btfe, &args[i].type),
> -		};
> -
> -		if (param.type == 0)
> +	for (i = 0; i < vlen; ++i, param++) {
> +		if (param->type == 0)
>  			proto->unspec_parms = 1;
>  		else {
>  			struct parameter *p = tag__alloc(sizeof(*p));
> @@ -68,25 +64,22 @@ static int btf_elf__load_ftype(struct btf_elf *btfe, struct ftype *proto, uint32
>  			if (p == NULL)
>  				goto out_free_parameters;
>  			p->tag.tag  = DW_TAG_formal_parameter;
> -			p->tag.type = param.type;
> -			p->name	    = param.name_off;
> +			p->tag.type = param->type;
> +			p->name	    = param->name_off;
>  			ftype__add_parameter(proto, p);
>  		}
>  	}
>  
> -	vlen *= sizeof(*args);
>  	cu__add_tag_with_id(btfe->priv, &proto->tag, id);
>  
> -	return vlen;
> +	return 0;
>  out_free_parameters:
>  	ftype__delete(proto, btfe->priv);
>  	return -ENOMEM;
>  }
>  
> -static int create_new_function(struct btf_elf *btfe, struct btf_type *tp, uint64_t size, uint32_t id)
> +static int create_new_function(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
>  {
> -	strings_t name = btf_elf__get32(btfe, &tp->name_off);
> -	unsigned int type_id = btf_elf__get32(btfe, &tp->type);
>  	struct function *func = tag__alloc(sizeof(*func));
>  
>  	if (func == NULL)
> @@ -96,8 +89,8 @@ static int create_new_function(struct btf_elf *btfe, struct btf_type *tp, uint64
>  	// but the prototype, the return type is the one in type_id
>  	func->btf = 1;
>  	func->proto.tag.tag = DW_TAG_subprogram;
> -	func->proto.tag.type = type_id;
> -	func->name = name;
> +	func->proto.tag.type = tp->type;
> +	func->name = tp->name_off;
>  	cu__add_tag_with_id(btfe->priv, &func->proto.tag, id);
>  
>  	return 0;
> @@ -165,26 +158,24 @@ static struct variable *variable__new(strings_t name, uint32_t linkage)
>  	return var;
>  }
>  
> -static int create_new_base_type(struct btf_elf *btfe, void *ptr, struct btf_type *tp, uint32_t id)
> +static int create_new_base_type(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
>  {
> -	uint32_t *enc = ptr;
> -	uint32_t eval = btf_elf__get32(btfe, enc);
> -	uint32_t attrs = BTF_INT_ENCODING(eval);
> -	strings_t name = btf_elf__get32(btfe, &tp->name_off);
> -	struct base_type *base = base_type__new(name, attrs, 0,
> -						BTF_INT_BITS(eval));
> +	uint32_t attrs = btf_int_encoding(tp);
> +	strings_t name = tp->name_off;
> +	struct base_type *base = base_type__new(name, attrs, 0, btf_int_bits(tp));
> +
>  	if (base == NULL)
>  		return -ENOMEM;
>  
>  	base->tag.tag = DW_TAG_base_type;
>  	cu__add_tag_with_id(btfe->priv, &base->tag, id);
>  
> -	return sizeof(*enc);
> +	return 0;
>  }
>  
> -static int create_new_array(struct btf_elf *btfe, void *ptr, uint32_t id)
> +static int create_new_array(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
>  {
> -	struct btf_array *ap = ptr;
> +	struct btf_array *ap = btf_array(tp);
>  	struct array_type *array = tag__alloc(sizeof(*array));
>  
>  	if (array == NULL)
> @@ -200,81 +191,67 @@ static int create_new_array(struct btf_elf *btfe, void *ptr, uint32_t id)
>  		return -ENOMEM;
>  	}
>  
> -	array->nr_entries[0] = btf_elf__get32(btfe, &ap->nelems);
> +	array->nr_entries[0] = ap->nelems;
>  	array->tag.tag = DW_TAG_array_type;
> -	array->tag.type = btf_elf__get32(btfe, &ap->type);
> +	array->tag.type = ap->type;
>  
>  	cu__add_tag_with_id(btfe->priv, &array->tag, id);
>  
> -	return sizeof(*ap);
> +	return 0;
>  }
>  
> -static int create_members(struct btf_elf *btfe, void *ptr, int vlen, struct type *class,
> -			  bool kflag)
> +static int create_members(struct btf_elf *btfe, const struct btf_type *tp,
> +			  struct type *class)
>  {
> -	struct btf_member *mp = ptr;
> -	int i;
> +	struct btf_member *mp = btf_members(tp);
> +	int i, vlen = btf_vlen(tp);
>  
>  	for (i = 0; i < vlen; i++) {
>  		struct class_member *member = zalloc(sizeof(*member));
> -		uint32_t offset;
>  
>  		if (member == NULL)
>  			return -ENOMEM;
>  
>  		member->tag.tag    = DW_TAG_member;
> -		member->tag.type   = btf_elf__get32(btfe, &mp[i].type);
> -		member->name	   = btf_elf__get32(btfe, &mp[i].name_off);
> -		offset = btf_elf__get32(btfe, &mp[i].offset);
> -		if (kflag) {
> -			member->bit_offset = BTF_MEMBER_BIT_OFFSET(offset);
> -			member->bitfield_size = BTF_MEMBER_BITFIELD_SIZE(offset);
> -		} else {
> -			member->bit_offset = offset;
> -			member->bitfield_size = 0;
> -		}
> +		member->tag.type   = mp[i].type;
> +		member->name	   = mp[i].name_off;
> +		member->bit_offset = btf_member_bit_offset(tp, i);
> +		member->bitfield_size = btf_member_bitfield_size(tp, i);
>  		member->byte_offset = member->bit_offset / 8;
>  		/* sizes and offsets will be corrected at class__fixup_btf_bitfields */
>  		type__add_member(class, member);
>  	}
>  
> -	return sizeof(*mp);
> +	return 0;
>  }
>  
> -static int create_new_class(struct btf_elf *btfe, void *ptr, int vlen,
> -			    struct btf_type *tp, uint64_t size, uint32_t id,
> -			    bool kflag)
> +static int create_new_class(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
>  {
> -	strings_t name = btf_elf__get32(btfe, &tp->name_off);
> -	struct class *class = class__new(name, size);
> -	int member_size = create_members(btfe, ptr, vlen, &class->type, kflag);
> +	struct class *class = class__new(tp->name_off, tp->size);
> +	int member_size = create_members(btfe, tp, &class->type);
>  
>  	if (member_size < 0)
>  		goto out_free;
>  
>  	cu__add_tag_with_id(btfe->priv, &class->type.namespace.tag, id);
>  
> -	return (vlen * member_size);
> +	return 0;
>  out_free:
>  	class__delete(class, btfe->priv);
>  	return -ENOMEM;
>  }
>  
> -static int create_new_union(struct btf_elf *btfe, void *ptr,
> -			    int vlen, struct btf_type *tp,
> -			    uint64_t size, uint32_t id,
> -			    bool kflag)
> +static int create_new_union(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
>  {
> -	strings_t name = btf_elf__get32(btfe, &tp->name_off);
> -	struct type *un = type__new(DW_TAG_union_type, name, size);
> -	int member_size = create_members(btfe, ptr, vlen, un, kflag);
> +	struct type *un = type__new(DW_TAG_union_type, tp->name_off, tp->size);
> +	int member_size = create_members(btfe, tp, un);
>  
>  	if (member_size < 0)
>  		goto out_free;
>  
>  	cu__add_tag_with_id(btfe->priv, &un->namespace.tag, id);
>  
> -	return (vlen * member_size);
> +	return 0;
>  out_free:
>  	type__delete(un, btfe->priv);
>  	return -ENOMEM;
> @@ -293,22 +270,20 @@ static struct enumerator *enumerator__new(strings_t name, uint32_t value)
>  	return en;
>  }
>  
> -static int create_new_enumeration(struct btf_elf *btfe, void *ptr,
> -				  int vlen, struct btf_type *tp,
> -				  uint16_t size, uint32_t id)
> +static int create_new_enumeration(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
>  {
> -	struct btf_enum *ep = ptr;
> -	uint16_t i;
> +	struct btf_enum *ep = btf_enum(tp);
> +	uint16_t i, vlen = btf_vlen(tp);
>  	struct type *enumeration = type__new(DW_TAG_enumeration_type,
> -					     btf_elf__get32(btfe, &tp->name_off),
> -					     size ? size * 8 : (sizeof(int) * 8));
> +					     tp->name_off,
> +					     tp->size ? tp->size * 8 : (sizeof(int) * 8));
>  
>  	if (enumeration == NULL)
>  		return -ENOMEM;
>  
>  	for (i = 0; i < vlen; i++) {
> -		strings_t name = btf_elf__get32(btfe, &ep[i].name_off);
> -		uint32_t value = btf_elf__get32(btfe, (uint32_t *)&ep[i].val);
> +		strings_t name = ep[i].name_off;
> +		uint32_t value = ep[i].val;
>  		struct enumerator *enumerator = enumerator__new(name, value);
>  
>  		if (enumerator == NULL)
> @@ -319,32 +294,25 @@ static int create_new_enumeration(struct btf_elf *btfe, void *ptr,
>  
>  	cu__add_tag_with_id(btfe->priv, &enumeration->namespace.tag, id);
>  
> -	return (vlen * sizeof(*ep));
> +	return 0;
>  out_free:
>  	enumeration__delete(enumeration, btfe->priv);
>  	return -ENOMEM;
>  }
>  
> -static int create_new_subroutine_type(struct btf_elf *btfe, void *ptr,
> -				      int vlen, struct btf_type *tp,
> -				      uint32_t id)
> +static int create_new_subroutine_type(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
>  {
> -	struct btf_param *args = ptr;
> -	unsigned int type = btf_elf__get32(btfe, &tp->type);
>  	struct ftype *proto = tag__alloc(sizeof(*proto));
>  
>  	if (proto == NULL)
>  		return -ENOMEM;
>  
> -	vlen = btf_elf__load_ftype(btfe, proto, DW_TAG_subroutine_type, type, vlen, args, id);
> -	return vlen < 0 ? -ENOMEM : vlen;
> +	return btf_elf__load_ftype(btfe, proto, DW_TAG_subroutine_type, tp, id);
>  }
>  
> -static int create_new_forward_decl(struct btf_elf *btfe, struct btf_type *tp,
> -				   uint64_t size, uint32_t id)
> +static int create_new_forward_decl(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
>  {
> -	strings_t name = btf_elf__get32(btfe, &tp->name_off);
> -	struct class *fwd = class__new(name, size);
> +	struct class *fwd = class__new(tp->name_off, 0);
>  
>  	if (fwd == NULL)
>  		return -ENOMEM;
> @@ -353,41 +321,33 @@ static int create_new_forward_decl(struct btf_elf *btfe, struct btf_type *tp,
>  	return 0;
>  }
>  
> -static int create_new_typedef(struct btf_elf *btfe, struct btf_type *tp, uint64_t size, uint32_t id)
> +static int create_new_typedef(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
>  {
> -	strings_t name = btf_elf__get32(btfe, &tp->name_off);
> -	unsigned int type_id = btf_elf__get32(btfe, &tp->type);
> -	struct type *type = type__new(DW_TAG_typedef, name, size);
> +	struct type *type = type__new(DW_TAG_typedef, tp->name_off, 0);
>  
>  	if (type == NULL)
>  		return -ENOMEM;
>  
> -	type->namespace.tag.type = type_id;
> +	type->namespace.tag.type = tp->type;
>  	cu__add_tag_with_id(btfe->priv, &type->namespace.tag, id);
>  
>  	return 0;
>  }
>  
> -static int create_new_variable(struct btf_elf *btfe, void *ptr, struct btf_type *tp,
> -			       uint64_t size, uint32_t id)
> +static int create_new_variable(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
>  {
> -	strings_t name = btf_elf__get32(btfe, &tp->name_off);
> -	unsigned int type_id = btf_elf__get32(btfe, &tp->type);
> -	struct btf_var *bvar = ptr;
> -	uint32_t linkage = btf_elf__get32(btfe, &bvar->linkage);
> -	struct variable *var = variable__new(name, linkage);
> +	struct btf_var *bvar = btf_var(tp);
> +	struct variable *var = variable__new(tp->name_off, bvar->linkage);
>  
>  	if (var == NULL)
>  		return -ENOMEM;
>  
> -	var->ip.tag.type = type_id;
> +	var->ip.tag.type = tp->type;
>  	cu__add_tag_with_id(btfe->priv, &var->ip.tag, id);
> -	return sizeof(*bvar);
> +	return 0;
>  }
>  
> -static int create_new_datasec(struct btf_elf *btfe, void *ptr, int vlen,
> -			      struct btf_type *tp, uint64_t size, uint32_t id,
> -			      bool kflag)
> +static int create_new_datasec(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
>  {
>  	//strings_t name = btf_elf__get32(btfe, &tp->name_off);
>  
> @@ -397,12 +357,11 @@ static int create_new_datasec(struct btf_elf *btfe, void *ptr, int vlen,
>  	 * FIXME: this will not be used to reconstruct some original C code,
>  	 * its about runtime placement of variables so just ignore this for now
>  	 */
> -	return vlen * sizeof(struct btf_var_secinfo);
> +	return 0;
>  }
>  
> -static int create_new_tag(struct btf_elf *btfe, int type, struct btf_type *tp, uint32_t id)
> +static int create_new_tag(struct btf_elf *btfe, int type, const struct btf_type *tp, uint32_t id)
>  {
> -	unsigned int type_id = btf_elf__get32(btfe, &tp->type);
>  	struct tag *tag = zalloc(sizeof(*tag));
>  
>  	if (tag == NULL)
> @@ -419,104 +378,77 @@ static int create_new_tag(struct btf_elf *btfe, int type, struct btf_type *tp, u
>  		return 0;
>  	}
>  
> -	tag->type = type_id;
> +	tag->type = tp->type;
>  	cu__add_tag_with_id(btfe->priv, tag, id);
>  
>  	return 0;
>  }
>  
> -void *btf_elf__get_buffer(struct btf_elf *btfe)
> -{
> -	return btfe->data;
> -}
> -
> -size_t btf_elf__get_size(struct btf_elf *btfe)
> -{
> -	return btfe->size;
> -}
> -
>  static int btf_elf__load_types(struct btf_elf *btfe)
>  {
> -	void *btf_buffer = btf_elf__get_buffer(btfe);
> -	struct btf_header *hp = btf_buffer;
> -	void *btf_contents = btf_buffer + sizeof(*hp),
> -	     *type_section = (btf_contents + btf_elf__get32(btfe, &hp->type_off)),
> -	     *strings_section = (btf_contents + btf_elf__get32(btfe, &hp->str_off));
> -	struct btf_type *type_ptr = type_section,
> -			*end = strings_section;
> -	uint32_t type_index = 0x0001;
> -
> -	while (type_ptr < end) {
> -		uint32_t val  = btf_elf__get32(btfe, &type_ptr->info);
> -		uint32_t type = BTF_INFO_KIND(val);
> -		int	 vlen = BTF_INFO_VLEN(val);
> -		void	 *ptr = type_ptr;
> -		uint32_t size = btf_elf__get32(btfe, &type_ptr->size);
> -		bool     kflag = BTF_INFO_KFLAG(val);
> -
> -		ptr += sizeof(struct btf_type);
> +	uint32_t type_index;
> +	int err;
> +
> +	for (type_index = 1; type_index <= btf__get_nr_types(btfe->btf); type_index++) {
> +		const struct btf_type *type_ptr = btf__type_by_id(btfe->btf, type_index);
> +		uint32_t type = btf_kind(type_ptr);
>  
>  		switch (type) {
>  		case BTF_KIND_INT:
> -			vlen = create_new_base_type(btfe, ptr, type_ptr, type_index);
> +			err = create_new_base_type(btfe, type_ptr, type_index);
>  			break;
>  		case BTF_KIND_ARRAY:
> -			vlen = create_new_array(btfe, ptr, type_index);
> +			err = create_new_array(btfe, type_ptr, type_index);
>  			break;
>  		case BTF_KIND_STRUCT:
> -			vlen = create_new_class(btfe, ptr, vlen, type_ptr, size, type_index, kflag);
> +			err = create_new_class(btfe, type_ptr, type_index);
>  			break;
>  		case BTF_KIND_UNION:
> -			vlen = create_new_union(btfe, ptr, vlen, type_ptr, size, type_index, kflag);
> +			err = create_new_union(btfe, type_ptr, type_index);
>  			break;
>  		case BTF_KIND_ENUM:
> -			vlen = create_new_enumeration(btfe, ptr, vlen, type_ptr, size, type_index);
> +			err = create_new_enumeration(btfe, type_ptr, type_index);
>  			break;
>  		case BTF_KIND_FWD:
> -			vlen = create_new_forward_decl(btfe, type_ptr, size, type_index);
> +			err = create_new_forward_decl(btfe, type_ptr, type_index);
>  			break;
>  		case BTF_KIND_TYPEDEF:
> -			vlen = create_new_typedef(btfe, type_ptr, size, type_index);
> +			err = create_new_typedef(btfe, type_ptr, type_index);
>  			break;
>  		case BTF_KIND_VAR:
> -			vlen = create_new_variable(btfe, ptr, type_ptr, size, type_index);
> +			err = create_new_variable(btfe, type_ptr, type_index);
>  			break;
>  		case BTF_KIND_DATASEC:
> -			vlen = create_new_datasec(btfe, ptr, vlen, type_ptr, size, type_index, kflag);
> +			err = create_new_datasec(btfe, type_ptr, type_index);
>  			break;
>  		case BTF_KIND_VOLATILE:
>  		case BTF_KIND_PTR:
>  		case BTF_KIND_CONST:
>  		case BTF_KIND_RESTRICT:
> -			vlen = create_new_tag(btfe, type, type_ptr, type_index);
> +			err = create_new_tag(btfe, type, type_ptr, type_index);
>  			break;
>  		case BTF_KIND_UNKN:
>  			cu__table_nullify_type_entry(btfe->priv, type_index);
> -			fprintf(stderr, "BTF: idx: %d, off: %zd, Unknown kind %d\n",
> -				type_index, ((void *)type_ptr) - type_section, type);
> +			fprintf(stderr, "BTF: idx: %d, Unknown kind %d\n", type_index, type);
>  			fflush(stderr);
> -			vlen = 0;
> +			err = 0;
>  			break;
>  		case BTF_KIND_FUNC_PROTO:
> -			vlen = create_new_subroutine_type(btfe, ptr, vlen, type_ptr, type_index);
> +			err = create_new_subroutine_type(btfe, type_ptr, type_index);
>  			break;
>  		case BTF_KIND_FUNC:
>  			// BTF_KIND_FUNC corresponding to a defined subprogram.
> -			vlen = create_new_function(btfe, type_ptr, size, type_index);
> +			err = create_new_function(btfe, type_ptr, type_index);
>  			break;
>  		default:
> -			fprintf(stderr, "BTF: idx: %d, off: %zd, Unknown kind %d\n",
> -				type_index, ((void *)type_ptr) - type_section, type);
> +			fprintf(stderr, "BTF: idx: %d, Unknown kind %d\n", type_index, type);
>  			fflush(stderr);
> -			vlen = 0;
> +			err = 0;
>  			break;
>  		}
>  
> -		if (vlen < 0)
> -			return vlen;
> -
> -		type_ptr = ptr + vlen;
> -		type_index++;
> +		if (err < 0)
> +			return err;
>  	}
>  	return 0;
>  }
> diff --git a/libbtf.c b/libbtf.c
> index 7a01ded4e612..02a55dbd7e13 100644
> --- a/libbtf.c
> +++ b/libbtf.c
> @@ -62,89 +62,29 @@ static int btf_var_secinfo_cmp(const void *a, const void *b)
>  	return av->offset - bv->offset;
>  }
>  
> -uint32_t btf_elf__get32(struct btf_elf *btfe, uint32_t *p)
> -{
> -	uint32_t val = *p;
> -
> -	if (btfe->swapped)
> -		val = ((val >> 24) |
> -		       ((val >> 8) & 0x0000ff00) |
> -		       ((val << 8) & 0x00ff0000) |
> -		       (val << 24));
> -	return val;
> -}
> -
> -static int btf_raw__load(struct btf_elf *btfe)
> +static int libbpf_log(enum libbpf_print_level level, const char *format, va_list args)
>  {
> -        size_t read_cnt;
> -        struct stat st;
> -        void *data;
> -        FILE *fp;
> -
> -        if (stat(btfe->filename, &st))
> -                return -1;
> -
> -        data = malloc(st.st_size);
> -        if (!data)
> -                return -1;
> -
> -        fp = fopen(btfe->filename, "rb");
> -        if (!fp)
> -                goto cleanup;
> -
> -        read_cnt = fread(data, 1, st.st_size, fp);
> -        fclose(fp);
> -        if (read_cnt < st.st_size)
> -                goto cleanup;
> -
> -	btfe->swapped	= 0;
> -	btfe->data	= data;
> -	btfe->size	= read_cnt;
> -	return 0;
> -cleanup:
> -        free(data);
> -        return -1;
> +	return vfprintf(stderr, format, args);
>  }
>  
>  int btf_elf__load(struct btf_elf *btfe)
>  {
> -	if (btfe->raw_btf)
> -		return btf_raw__load(btfe);
> -
> -	int err = -ENOTSUP;
> -	GElf_Shdr shdr;
> -	Elf_Scn *sec = elf_section_by_name(btfe->elf, &btfe->ehdr, &shdr, ".BTF", NULL);
> +	int err;
>  
> -	if (sec == NULL)
> -		return -ESRCH;
> -
> -	Elf_Data *data = elf_getdata(sec, NULL);
> -	if (data == NULL) {
> -		fprintf(stderr, "%s: cannot get data of BTF section.\n", __func__);
> -		return -1;
> -	}
> -
> -	struct btf_header *hp = data->d_buf;
> -	size_t orig_size = data->d_size;
> -
> -	if (hp->version != BTF_VERSION)
> -		goto out;
> +	libbpf_set_print(libbpf_log);
>  
> -	err = -EINVAL;
> -	if (hp->magic == BTF_MAGIC)
> -		btfe->swapped = 0;
> +	/* free initial empty BTF */
> +	btf__free(btfe->btf);
> +	if (btfe->raw_btf)
> +		btfe->btf = btf__parse_raw(btfe->filename);
>  	else
> -		goto out;
> +		btfe->btf = btf__parse_elf(btfe->filename, NULL);
>  
> -	err = -ENOMEM;
> -	btfe->data = malloc(orig_size);
> -	if (btfe->data != NULL) {
> -		memcpy(btfe->data, hp, orig_size);
> -		btfe->size = orig_size;
> -		err = 0;
> -	}
> -out:
> -	return err;
> +	err = libbpf_get_error(btfe->btf);
> +	if (err)
> +		return err;
> +
> +	return 0;
>  }
>  
>  
> @@ -251,26 +191,17 @@ void btf_elf__delete(struct btf_elf *btfe)
>  
>  	__gobuffer__delete(&btfe->types);
>  	__gobuffer__delete(&btfe->percpu_secinfo);
> +	btf__free(btfe->btf);
>  	free(btfe->filename);
>  	free(btfe->data);
>  	free(btfe);
>  }
>  
> -char *btf_elf__string(struct btf_elf *btfe, uint32_t ref)
> +const char *btf_elf__string(struct btf_elf *btfe, uint32_t ref)
>  {
> -	struct btf_header *hp = btfe->hdr;
> -	uint32_t off = ref;
> -	char *name;
> -
> -	if (off >= btf_elf__get32(btfe, &hp->str_len))
> -		return "(ref out-of-bounds)";
> -
> -	if ((off + btf_elf__get32(btfe, &hp->str_off)) >= btfe->size)
> -		return "(string table truncated)";
> +	const char *s = btf__str_by_offset(btfe->btf, ref);
>  
> -	name = ((char *)(hp + 1) + btf_elf__get32(btfe, &hp->str_off) + off);
> -
> -	return name[0] == '\0' ? NULL : name;
> +	return s && s[0] == '\0' ? NULL : s;
>  }
>  
>  static void *btf_elf__nohdr_data(struct btf_elf *btfe)
> @@ -310,8 +241,10 @@ static const char *btf_elf__name_in_gobuf(const struct btf_elf *btfe, uint32_t o
>  {
>  	if (!offset)
>  		return "(anon)";
> -	else
> +	else if (btfe->strings)
>  		return &btfe->strings->entries[offset];
> +	else
> +		return btf__str_by_offset(btfe->btf, offset);
>  }
>  
>  static const char * btf_elf__int_encoding_str(uint8_t encoding)
> @@ -836,11 +769,6 @@ out:
>  	return err;
>  }
>  
> -static int libbpf_log(enum libbpf_print_level level, const char *format, va_list args)
> -{
> -	return vfprintf(stderr, format, args);
> -}
> -
>  int btf_elf__encode(struct btf_elf *btfe, uint8_t flags)
>  {
>  	struct btf_header *hdr;
> @@ -886,7 +814,7 @@ int btf_elf__encode(struct btf_elf *btfe, uint8_t flags)
>  		return -1;
>  	}
>  	if (btf__dedup(btf, NULL, NULL)) {
> -		fprintf(stderr, "%s: btf__dedup failed!", __func__);
> +		fprintf(stderr, "%s: btf__dedup failed!\n", __func__);
>  		return -1;
>  	}
>  
> diff --git a/libbtf.h b/libbtf.h
> index be06480bf854..5f29b427c4fd 100644
> --- a/libbtf.h
> +++ b/libbtf.h
> @@ -11,6 +11,7 @@
>  
>  #include <stdbool.h>
>  #include <stdint.h>
> +#include "lib/bpf/src/btf.h"
>  
>  struct btf_elf {
>  	union {
> @@ -26,7 +27,6 @@ struct btf_elf {
>  	struct gobuffer   percpu_secinfo;
>  	char		  *filename;
>  	size_t		  size;
> -	int		  swapped;
>  	int		  in_fd;
>  	uint8_t		  wordsize;
>  	bool		  is_big_endian;
> @@ -34,6 +34,7 @@ struct btf_elf {
>  	uint32_t	  type_index;
>  	uint32_t	  percpu_shndx;
>  	uint64_t	  percpu_base_addr;
> +	struct btf	  *btf;
>  };
>  
>  extern uint8_t btf_elf__verbose;
> @@ -70,13 +71,7 @@ int32_t btf_elf__add_datasec_type(struct btf_elf *btfe, const char *section_name
>  void btf_elf__set_strings(struct btf_elf *btf, struct gobuffer *strings);
>  int  btf_elf__encode(struct btf_elf *btf, uint8_t flags);
>  
> -char *btf_elf__string(struct btf_elf *btf, uint32_t ref);
> +const char *btf_elf__string(struct btf_elf *btf, uint32_t ref);
>  int btf_elf__load(struct btf_elf *btf);
>  
> -uint32_t btf_elf__get32(struct btf_elf *btf, uint32_t *p);
> -
> -void *btf_elf__get_buffer(struct btf_elf *btf);
> -
> -size_t btf_elf__get_size(struct btf_elf *btf);
> -
>  #endif /* _LIBBTF_H */
> -- 
> 2.24.1
> 

-- 

- Arnaldo

  reply index

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-30  4:27 [PATCH dwarves 00/11] Switch BTF loading and encoding to libbpf APIs Andrii Nakryiko
2020-09-30  4:27 ` [PATCH dwarves 01/11] libbpf: update to latest libbpf version Andrii Nakryiko
2020-09-30  4:27 ` [PATCH dwarves 02/11] btf_encoder: detect BTF encoding errors and exit Andrii Nakryiko
2020-09-30  4:27 ` [PATCH dwarves 03/11] dwarves: expose and maintain active debug info loader operations Andrii Nakryiko
2020-09-30  4:27 ` [PATCH dwarves 04/11] btf_loader: use libbpf to load BTF Andrii Nakryiko
2020-10-08 18:06   ` Arnaldo Carvalho de Melo [this message]
2020-10-08 19:32     ` Andrii Nakryiko
2020-09-30  4:27 ` [PATCH dwarves 05/11] btf_encoder: use libbpf APIs to encode BTF type info Andrii Nakryiko
2020-09-30  4:27 ` [PATCH dwarves 06/11] btf_encoder: fix emitting __ARRAY_SIZE_TYPE__ as index range type Andrii Nakryiko
2020-09-30  4:27 ` [PATCH dwarves 07/11] btf_encoder: discard CUs after BTF encoding Andrii Nakryiko
2020-09-30  4:27 ` [PATCH dwarves 08/11] btf_encoder: revamp how per-CPU variables are encoded Andrii Nakryiko
2020-09-30  4:27 ` [PATCH dwarves 09/11] dwarf_loader: increase the size of lookup hash map Andrii Nakryiko
2020-09-30  4:27 ` [PATCH dwarves 10/11] strings: use BTF's string APIs for strings management Andrii Nakryiko
2020-09-30  4:27 ` [PATCH dwarves 11/11] btf_encoder: support cross-compiled ELF binaries with different endianness Andrii Nakryiko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201008180651.GD246083@kernel.org \
    --to=acme@kernel.org \
    --cc=andriin@fb.com \
    --cc=bpf@vger.kernel.org \
    --cc=dwarves@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Dwarves Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/dwarves/0 dwarves/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dwarves dwarves/ https://lore.kernel.org/dwarves \
		dwarves@vger.kernel.org
	public-inbox-index dwarves

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.dwarves


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git