[PATCH 1/2] bfd: add basic support for BTF debug info
Jose E. Marchesi
jemarch@gnu.org
Wed Sep 30 18:36:00 GMT 2026
Hi Faust.
The patch LGTM.
Assuming that BTF falls within the BPF realm (which I think it is a fair
assumption, but please wait for a day or so in case some global
maintainer has some objection) this patch is OK.
> This patch adds basic support for the BPF Type Format (BTF) to BFD.
> This includes definitions for data structures and helper functions for
> decoding the format.
>
> The added include/btf.h is copied from gcc and extended with prototypes
> for helper functions implemented in BFD. The intent is to keep the data
> structure names, definitions, macros, etc in sync with that of gcc's
> btf.h (which in turn is based off of the Linux kernel BTF definitions).
>
> Signed-off-by: David Faust <david.faust@oss.qualcomm.com>
> ---
> bfd/Makefile.am | 10 +-
> bfd/Makefile.in | 12 +--
> bfd/btf.c | 265 +++++++++++++++++++++++++++++++++++++++++++++
> include/btf.h | 282 ++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 558 insertions(+), 11 deletions(-)
> create mode 100644 bfd/btf.c
> create mode 100644 include/btf.h
>
> diff --git a/bfd/Makefile.am b/bfd/Makefile.am
> index e4df05441eb..506e84b0470 100644
> --- a/bfd/Makefile.am
> +++ b/bfd/Makefile.am
> @@ -75,7 +75,7 @@ BFD_H = bfd.h
> # need two copies of the executable, one to download and one for the
> # debugger).
> BFD32_LIBS = \
> - archive.lo archures.lo bfd.lo bfdio.lo cache.lo \
> + archive.lo archures.lo bfd.lo bfdio.lo btf.lo cache.lo \
> coff-bfd.lo compress.lo corefile.lo format.lo \
> hash.lo libbfd.lo linker.lo merge.lo opncls.lo reloc.lo \
> section.lo simple.lo stab-syms.lo stabs.lo syms.lo targets.lo \
> @@ -84,7 +84,7 @@ BFD32_LIBS = \
> BFD64_LIBS = archive64.lo
>
> BFD32_LIBS_CFILES = \
> - archive.c archures.c bfd.c bfdio.c cache.c coff-bfd.c \
> + archive.c archures.c bfd.c bfdio.c btf.c cache.c coff-bfd.c \
> compress.c corefile.c format.c hash.c \
> libbfd.c linker.c merge.c opncls.c reloc.c \
> section.c simple.c stab-syms.c stabs.c syms.c targets.c \
> @@ -700,7 +700,7 @@ CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
> ## This is a list of all .h files in the source tree minus those that
> ## are processed to produce other .h files
> SOURCE_HFILES = \
> - aout-target.h aoutx.h arc-got.h arc-plt.h \
> + aout-target.h aoutx.h arc-got.h arc-plt.h btf.h \
> coff-arm.h coff-bfd.h coffcode.h coffswap.h \
> cpu-aarch64.h cpu-arm.h cpu-h8300.h cpu-m68k.h cpu-riscv.h \
> ecoff-bfd.h ecoffswap.h \
> @@ -926,11 +926,11 @@ stmp-bfd-h: bfd-in3.h
> touch stmp-bfd-h
>
> BFD_H_FILES = bfd-in.h libbfd.c hash.c section.c syms.c \
> - archive.c archures.c bfd.c bfdio.c \
> + archive.c archures.c bfd.c bfdio.c btf.c \
> cache.c compress.c corefile.c format.c linker.c opncls.c \
> reloc.c simple.c stab-syms.c stabs.c targets.c
> BFD64_H_FILES = archive64.c
> -LIBBFD_H_FILES = libbfd-in.h libbfd.c bfd.c bfdio.c \
> +LIBBFD_H_FILES = libbfd-in.h libbfd.c bfd.c bfdio.c btf.c \
> archive.c archures.c cache.c hash.c linker.c opncls.c \
> reloc.c section.c stabs.c targets.c
> LIBCOFF_H_FILES = libcoff-in.h coffcode.h
> diff --git a/bfd/Makefile.in b/bfd/Makefile.in
> index 14512cf61fb..ee97aa48e86 100644
> --- a/bfd/Makefile.in
> +++ b/bfd/Makefile.in
> @@ -180,7 +180,7 @@ am__installdirs = "$(DESTDIR)$(bfdlibdir)" "$(DESTDIR)$(infodir)" \
> "$(DESTDIR)$(bfdincludedir)"
> LTLIBRARIES = $(bfdlib_LTLIBRARIES) $(noinst_LTLIBRARIES)
> am__DEPENDENCIES_1 =
> -am__objects_1 = archive.lo archures.lo bfd.lo bfdio.lo cache.lo \
> +am__objects_1 = archive.lo archures.lo bfd.lo bfdio.lo btf.lo cache.lo \
> coff-bfd.lo compress.lo corefile.lo format.lo hash.lo \
> libbfd.lo linker.lo merge.lo opncls.lo reloc.lo section.lo \
> simple.lo stab-syms.lo stabs.lo syms.lo targets.lo binary.lo \
> @@ -544,7 +544,7 @@ BFD_H = bfd.h
> # need two copies of the executable, one to download and one for the
> # debugger).
> BFD32_LIBS = \
> - archive.lo archures.lo bfd.lo bfdio.lo cache.lo \
> + archive.lo archures.lo bfd.lo bfdio.lo btf.lo cache.lo \
> coff-bfd.lo compress.lo corefile.lo format.lo \
> hash.lo libbfd.lo linker.lo merge.lo opncls.lo reloc.lo \
> section.lo simple.lo stab-syms.lo stabs.lo syms.lo targets.lo \
> @@ -552,7 +552,7 @@ BFD32_LIBS = \
>
> BFD64_LIBS = archive64.lo
> BFD32_LIBS_CFILES = \
> - archive.c archures.c bfd.c bfdio.c cache.c coff-bfd.c \
> + archive.c archures.c bfd.c bfdio.c btf.c cache.c coff-bfd.c \
> compress.c corefile.c format.c hash.c \
> libbfd.c linker.c merge.c opncls.c reloc.c \
> section.c simple.c stab-syms.c stabs.c syms.c targets.c \
> @@ -1166,7 +1166,7 @@ BUILD_CFILES = \
>
> CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
> SOURCE_HFILES = \
> - aout-target.h aoutx.h arc-got.h arc-plt.h \
> + aout-target.h aoutx.h arc-got.h arc-plt.h btf.h \
> coff-arm.h coff-bfd.h coffcode.h coffswap.h \
> cpu-aarch64.h cpu-arm.h cpu-h8300.h cpu-m68k.h cpu-riscv.h \
> ecoff-bfd.h ecoffswap.h \
> @@ -1219,12 +1219,12 @@ EXTRA_libbfd_la_SOURCES = $(CFILES)
> libbfd_la_DEPENDENCIES = $(OFILES) ofiles ../libsframe/libsframe.la
> libbfd_la_LIBADD = `cat ofiles` @SHARED_LIBADD@ $(LIBDL) $(ZLIB) $(ZSTD_LIBS) ../libsframe/libsframe.la
> BFD_H_FILES = bfd-in.h libbfd.c hash.c section.c syms.c \
> - archive.c archures.c bfd.c bfdio.c \
> + archive.c archures.c bfd.c bfdio.c btf.c \
> cache.c compress.c corefile.c format.c linker.c opncls.c \
> reloc.c simple.c stab-syms.c stabs.c targets.c
>
> BFD64_H_FILES = archive64.c
> -LIBBFD_H_FILES = libbfd-in.h libbfd.c bfd.c bfdio.c \
> +LIBBFD_H_FILES = libbfd-in.h libbfd.c bfd.c bfdio.c btf.c \
> archive.c archures.c cache.c hash.c linker.c opncls.c \
> reloc.c section.c stabs.c targets.c
>
> diff --git a/bfd/btf.c b/bfd/btf.c
> new file mode 100644
> index 00000000000..638ac84cd92
> --- /dev/null
> +++ b/bfd/btf.c
> @@ -0,0 +1,265 @@
> +/* btf.c -- display BTF contents of a BFD binary file
> + Copyright (C) 2026 Free Software Foundation, Inc.
> +
> + This file is part of GNU Binutils.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program; if not, write to the Free Software
> + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
> + 02110-1301, USA. */
> +
> +#include "sysdep.h"
> +#include "bfd.h"
> +#include "libbfd.h"
> +#include "btf.h"
> +
> +struct btf_header *
> +btf_read_header (bfd *abfd, bfd_byte *buf)
> +{
> + struct btf_header *header = bfd_zmalloc (sizeof (struct btf_header));
> +
> + header->magic = bfd_get_16 (abfd, buf);
> + buf += 2;
> + header->version = bfd_get_8 (abfd, buf);
> + buf += 1;
> + header->flags = bfd_get_8 (abfd, buf);
> + buf += 1;
> + header->hdr_len = bfd_get_32 (abfd, buf);
> + buf += 4;
> + header->type_off = bfd_get_32 (abfd, buf);
> + buf += 4;
> + header->type_len = bfd_get_32 (abfd, buf);
> + buf += 4;
> + header->str_off = bfd_get_32 (abfd, buf);
> + buf += 4;
> + header->str_len = bfd_get_32 (abfd, buf);
> +
> + return header;
> +}
> +
> +struct btf_type *
> +btf_read_type (bfd *abfd, bfd_byte *buf)
> +{
> + struct btf_type *typ = bfd_zmalloc (sizeof (struct btf_type));
> +
> + typ->name_off = bfd_get_32 (abfd, buf);
> + buf += 4;
> + typ->info = bfd_get_32 (abfd, buf);
> + buf += 4;
> + typ->size = bfd_get_32 (abfd, buf);
> +
> + return typ;
> +}
> +
> +struct btf_member *
> +btf_read_member (bfd *abfd, bfd_byte *buf)
> +{
> + struct btf_member *member = bfd_zmalloc (sizeof (struct btf_member));
> +
> + member->name_off = bfd_get_32 (abfd, buf);
> + buf += 4;
> + member->type = bfd_get_32 (abfd, buf);
> + buf += 4;
> + member->offset = bfd_get_32 (abfd, buf);
> +
> + return member;
> +}
> +
> +struct btf_decl_tag *
> +btf_read_decl_tag (bfd *abfd, bfd_byte *buf)
> +{
> + struct btf_decl_tag *decl_tag = bfd_zmalloc (sizeof (struct btf_decl_tag));
> +
> + decl_tag->component_idx = bfd_get_32 (abfd, buf);
> + return decl_tag;
> +}
> +
> +struct btf_var_secinfo *
> +btf_read_var_secinfo (bfd *abfd, bfd_byte *buf)
> +{
> + struct btf_var_secinfo *var_secinfo = bfd_zmalloc (sizeof (struct btf_var_secinfo));
> +
> + var_secinfo->type = bfd_get_32 (abfd, buf);
> + buf += 4;
> + var_secinfo->offset = bfd_get_32 (abfd, buf);
> + buf += 4;
> + var_secinfo->size = bfd_get_32 (abfd, buf);
> +
> + return var_secinfo;
> +}
> +
> +struct btf_var *
> +btf_read_var (bfd *abfd, bfd_byte *buf)
> +{
> + struct btf_var *var = bfd_zmalloc (sizeof (struct btf_var));
> +
> + var->linkage = bfd_get_32 (abfd, buf);
> + return var;
> +}
> +
> +struct btf_param *
> +btf_read_param (bfd *abfd, bfd_byte *buf)
> +{
> + struct btf_param *param = bfd_zmalloc (sizeof (struct btf_param));
> +
> + param->name_off = bfd_get_32 (abfd, buf);
> + buf += 4;
> + param->type = bfd_get_32 (abfd, buf);
> +
> + return param;
> +}
> +
> +struct btf_enum64 *
> +btf_read_enum64 (bfd *abfd, bfd_byte *buf)
> +{
> + struct btf_enum64 *enum64 = bfd_zmalloc (sizeof (struct btf_enum64));
> +
> + enum64->name_off = bfd_get_32 (abfd, buf);
> + buf += 4;
> + enum64->val_lo32 = bfd_get_32 (abfd, buf);
> + buf += 4;
> + enum64->val_hi32 = bfd_get_32 (abfd, buf);
> +
> + return enum64;
> +}
> +
> +struct btf_enum *
> +btf_read_enum (bfd *abfd, bfd_byte *buf)
> +{
> + struct btf_enum *anenum = bfd_zmalloc (sizeof (struct btf_enum));
> +
> + anenum->name_off = bfd_get_32 (abfd, buf);
> + buf += 4;
> + anenum->val = bfd_get_32 (abfd, buf);
> +
> + return anenum;
> +}
> +
> +struct btf_array *
> +btf_read_array (bfd *abfd, bfd_byte *buf)
> +{
> + struct btf_array *array = bfd_zmalloc (sizeof (struct btf_array));
> +
> + array->type = bfd_get_32 (abfd, buf);
> + buf += 4;
> + array->index_type = bfd_get_32 (abfd, buf);
> + buf += 4;
> + array->nelems = bfd_get_32 (abfd, buf);
> +
> + return array;
> +}
> +
> +uint32_t
> +btf_read_integral (bfd *abfd, bfd_byte *buf)
> +{
> + return bfd_get_32 (abfd, buf);
> +}
> +
> +bfd_vma
> +btf_type_size (struct btf_type *entry)
> +{
> + bfd_vma size = sizeof (struct btf_type);
> + uint16_t vlen = BTF_INFO_VLEN (entry->info);
> +
> + switch (BTF_INFO_KIND (entry->info))
> + {
> + case BTF_KIND_INT:
> + size += 4;
> + break;
> + case BTF_KIND_ARRAY:
> + size += sizeof (struct btf_array);
> + break;
> + case BTF_KIND_ENUM:
> + size += sizeof (struct btf_enum) * vlen;
> + break;
> + case BTF_KIND_ENUM64:
> + size += sizeof (struct btf_enum64) * vlen;
> + break;
> + case BTF_KIND_FUNC_PROTO:
> + size += sizeof (struct btf_param) * vlen;
> + break;
> + case BTF_KIND_VAR:
> + size += sizeof (struct btf_var);
> + break;
> + case BTF_KIND_UNION:
> + /* Fallthrough. */
> + case BTF_KIND_STRUCT:
> + size += sizeof (struct btf_member) * vlen;
> + break;
> + case BTF_KIND_DATASEC:
> + size += sizeof (struct btf_var_secinfo) * vlen;
> + break;
> + case BTF_KIND_DECL_TAG:
> + size += sizeof (struct btf_decl_tag);
> + break;
> + default:
> + /* No entry specific additional data follows this entry. */
> + break;
> + }
> +
> + return size;
> +}
> +
> +bool
> +btf_map (bfd *abfd, asection *sec, btf_type_map_cb cb)
> +{
> + bfd_byte *btfdata = NULL;
> + struct btf_header *header = NULL;
> + bfd_size_type section_size = bfd_section_size (sec);
> +
> + if (!bfd_malloc_and_get_section (abfd, sec, &btfdata))
> + goto error;
> +
> + header = btf_read_header (abfd, btfdata);
> + if (header->magic != 0xeb9f)
> + goto error;
> +
> + if (header->version != 1)
> + goto error;
> +
> + /* Make sure the BTF regions specified by the header (entries and
> + string table) fall within the section. A corrupted header may
> + lead to a buffer overflow below. */
> +
> + if (header->hdr_len + header->str_off + header->str_len > section_size
> + || header->hdr_len + header->type_off + header->type_len > section_size)
> + goto error;
> +
> + /* Iterate over all the entries in the section and invoke the user
> + provided callback. */
> + {
> + bfd_byte *str_base = btfdata + header->hdr_len + header->str_off;
> + bfd_byte *type_base = btfdata + header->hdr_len + header->type_off;
> + bfd_byte *type_off = type_base;
> + uint32_t type_id = 1;
> +
> + while (type_off < type_base + header->type_len)
> + {
> + struct btf_type *t = btf_read_type (abfd, type_off);
> +
> + (*cb) (abfd, btfdata,
> + str_base - btfdata,
> + type_off - btfdata,
> + type_id++, t);
> + type_off += btf_type_size (t);
> + free (t);
> + }
> + }
> +
> + free (btfdata);
> + return true;
> +
> + error:
> + free (btfdata);
> + return false;
> +}
> diff --git a/include/btf.h b/include/btf.h
> new file mode 100644
> index 00000000000..2a81c35ebe5
> --- /dev/null
> +++ b/include/btf.h
> @@ -0,0 +1,282 @@
> +/* btf.h - BTF support header file
> + Copyright (C) 2026 Free Software Foundation, Inc.
> +
> + This file is part of GNU Binutils.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program; if not, write to the Free Software
> + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
> + MA 02110-1301, USA. */
> +
> +#ifndef BTF_H
> +#define BTF_H
> +
> +/* BTF magic number to identify header, endianness. */
> +#define BTF_MAGIC 0xeb9f
> +/* Data format version number. */
> +#define BTF_VERSION 1
> +
> +struct btf_header
> +{
> + uint16_t magic; /* Magic number (BTF_MAGIC). */
> + uint8_t version; /* Data format version (BTF_VERSION). */
> + uint8_t flags; /* Flags. Currently unused. */
> + uint32_t hdr_len; /* Length of this header (sizeof (struct btf_header)). */
> +
> + /* Following offsets are relative to the end of this header. */
> + uint32_t type_off; /* Offset of type section, in bytes. */
> + uint32_t type_len; /* Length of type section, in bytes. */
> + uint32_t str_off; /* Offset of string section, in bytes. */
> + uint32_t str_len; /* Length of string section, in bytes. */
> +};
> +
> +/* Maximum type identifier. */
> +#define BTF_MAX_TYPE 0x000fffff
> +/* Maximum offset into the string section. */
> +#define BTF_MAX_NAME_OFFSET 0x00ffffff
> +/* Maximum number of struct, union, enum members or func args. */
> +#define BTF_MAX_VLEN 0xffff
> +
> +/* Type ID 0 represents the void type. */
> +#define BTF_VOID_TYPEID 0
> +/* Initial type ID for regular types. */
> +#define BTF_INIT_TYPEID 1
> +
> +struct btf_type
> +{
> + uint32_t name_off; /* Offset in string section of type name. */
> + uint32_t info; /* Encoded kind, variant length, kind flag:
> + - bits 0-15: vlen
> + - bits 16-23: unused
> + - bits 24-28: kind
> + - bits 29-30: unused
> + - bit 31: kind_flag
> + See accessor macros below. */
> +
> + /* SIZE is used by INT, ENUM, STRUCT, UNION, DATASEC kinds.
> + TYPE is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT, FUNC,
> + FUNC_PROTO and VAR kinds. */
> + union
> + {
> + uint32_t size; /* Size of the entire type, in bytes. */
> + uint32_t type; /* A type_id referring to another type. */
> + };
> +};
> +
> +/* The following macros access the information encoded in btf_type.info. */
> +/* Type kind. See below. */
> +#define BTF_INFO_KIND(info) (((info) >> 24) & 0x1f)
> +/* Number of entries of variable length data following certain type kinds.
> + For example, number of structure members, number of function parameters. */
> +#define BTF_INFO_VLEN(info) ((info) & 0xffff)
> +/* For BTF_KIND_FWD, 1 if forward to union, 0 if forward to struct.
> + For BTF_KIND_STRUCT and BTF_KIND_UNION, 1 if the struct/union contains
> + a bitfield. */
> +#define BTF_INFO_KFLAG(info) ((info) >> 31)
> +
> +/* Encoding for struct btf_type.info. */
> +#define BTF_TYPE_INFO(kind, kflag, vlen) \
> + ((((kflag) ? 1 : 0 ) << 31) | ((kind & 0x1f) << 24) | ((vlen) & 0xffff))
> +
> +#define BTF_KIND_UNKN 0 /* Unknown or invalid. */
> +#define BTF_KIND_INT 1 /* Integer. */
> +#define BTF_KIND_PTR 2 /* Pointer. */
> +#define BTF_KIND_ARRAY 3 /* Array. */
> +#define BTF_KIND_STRUCT 4 /* Struct. */
> +#define BTF_KIND_UNION 5 /* Union. */
> +#define BTF_KIND_ENUM 6 /* Enumeration. */
> +#define BTF_KIND_FWD 7 /* Forward. */
> +#define BTF_KIND_TYPEDEF 8 /* Typedef. */
> +#define BTF_KIND_VOLATILE 9 /* Referenced type is volatile. */
> +#define BTF_KIND_CONST 10 /* Referenced type is const. */
> +#define BTF_KIND_RESTRICT 11 /* Restrict. */
> +#define BTF_KIND_FUNC 12 /* Subprogram. */
> +#define BTF_KIND_FUNC_PROTO 13 /* Function Prototype. */
> +#define BTF_KIND_VAR 14 /* Variable. */
> +#define BTF_KIND_DATASEC 15 /* Section such as .bss or .data. */
> +#define BTF_KIND_FLOAT 16 /* Floating point. */
> +#define BTF_KIND_DECL_TAG 17 /* Declaration tag. */
> +#define BTF_KIND_TYPE_TAG 18 /* Type tag. */
> +#define BTF_KIND_ENUM64 19 /* Enumeration up to 64 bits. */
> +#define BTF_KIND_MAX BTF_KIND_ENUM64
> +#define NR_BTF_KINDS (BTF_KIND_MAX + 1)
> +
> +/* For some BTF_KINDs, struct btf_type is immediately followed by
> + additional data describing the type. */
> +
> +/* BTF_KIND_INT is followed by a 32-bit word, with the following
> + bit arrangement. */
> +#define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24)
> +#define BTF_INT_OFFSET(VAL) (((VAL) & 0x00ff0000) >> 16)
> +#define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff)
> +
> +#define BTF_INT_DATA(encoding, offset, bits) \
> + ((((encoding) & 0x0f) << 24) | (((offset) & 0xff) << 16) | ((bits) & 0xff))
> +
> +/* BTF_INT_ENCODING holds the following attribute flags. */
> +#define BTF_INT_SIGNED (1 << 0)
> +#define BTF_INT_CHAR (1 << 1)
> +#define BTF_INT_BOOL (1 << 2)
> +
> +/* BTF_KIND_ENUM is followed by VLEN struct btf_enum entries,
> + which describe the enumerators. */
> +struct btf_enum
> +{
> + uint32_t name_off; /* Offset in string section of enumerator name. */
> + int32_t val; /* Enumerator value. */
> +};
> +
> +/* BTF_KF_ENUM_ holds the flags for kflags in BTF_KIND_ENUM{,64}. */
> +#define BTF_KF_ENUM_UNSIGNED (0)
> +#define BTF_KF_ENUM_SIGNED (1 << 0)
> +
> +/* BTF_KIND_ARRAY is followed by a single struct btf_array. */
> +struct btf_array
> +{
> + uint32_t type; /* Type of array elements. */
> + uint32_t index_type; /* Type of array index. */
> + uint32_t nelems; /* Number of elements. 0 for unsized/variable length. */
> +};
> +
> +/* BTF_KIND_STRUCT and BTF_KIND_UNION are followed by VLEN
> + struct btf_member. */
> +struct btf_member
> +{
> + uint32_t name_off; /* Offset in string section of member name. */
> + uint32_t type; /* Type of member. */
> + uint32_t offset; /* If the type info kind_flag is set, this contains
> + both the member bitfield size and bit offset,
> + according to the macros below. If kind_flag is not
> + set, offset contains only the bit offset (from the
> + beginning of the struct). */
> +};
> +
> +/* If struct or union type info kind_flag is set, used to access member
> + bitfield size from btf_member.offset. */
> +#define BTF_MEMBER_BITFIELD_SIZE(VAL) ((VAL) >> 24)
> +/* If struct or union type info kind_flag is set, used to access member
> + bit offset from btf_member.offset. */
> +#define BTF_MEMBER_BITFIELD_OFFSET(VAL) ((VAL) & 0x00ffffff)
> +
> +/* BTF_KIND_FUNC_PROTO is followed by VLEN struct btf_param entries, which
> + describe the types of the function parameters. */
> +struct btf_param
> +{
> + uint32_t name_off; /* Offset in string section of parameter name. */
> + uint32_t type; /* Type of parameter. */
> +};
> +
> +/* BTF_KIND_FUNC records encode linkage information in the VLEN bits
> + of the type record. These are the supported values. */
> +enum btf_func_linkage
> +{
> + BTF_FUNC_STATIC = 0,
> + BTF_FUNC_GLOBAL = 1,
> + BTF_FUNC_EXTERN = 2,
> +};
> +
> +/* BTF_KIND_VAR records encode linkage information in a single
> + trailing struct btf_var. These are the supported values. */
> +enum btf_var_linkage
> +{
> + BTF_VAR_STATIC = 0,
> + BTF_VAR_GLOBAL_ALLOCATED = 1,
> + BTF_VAR_GLOBAL_EXTERN = 2,
> +};
> +
> +/* BTF_KIND_VAR is followed by a single struct btf_var, which describes
> + information about the variable. */
> +struct btf_var
> +{
> + uint32_t linkage; /* 0=static, 1=global, 2=extern. */
> +};
> +
> +/* BTF_KIND_DATASEC is followed by VLEN struct btf_var_secinfo entries,
> + which describe all BTF_KIND_VAR or extern BTF_KIND_FUNC types contained
> + in the section. */
> +struct btf_var_secinfo
> +{
> + uint32_t type; /* Type of BTF_KIND_VAR or BTF_KIND_FUNC item. */
> + uint32_t offset; /* In-section offset (in bytes) of item. */
> + uint32_t size; /* Size (in bytes) of item. */
> +};
> +
> +/* BTF_KIND_ENUM64 is followed by VLEN struct btf_enum64 entries,
> + which describe the 64 bits enumerators. */
> +struct btf_enum64
> +{
> + uint32_t name_off; /* Offset in string section of enumerator name. */
> + uint32_t val_lo32; /* lower 32-bit value for a 64-bit value Enumerator */
> + uint32_t val_hi32; /* high 32-bit value for a 64-bit value Enumerator */
> +};
> +
> +/* BTF_KIND_DECL_TAG is followed by a single struct btf_decl_tag, which
> + describes the item to which the tag applies:
> + - If component_idx == (uint32_t) -1, then the tag applies to item referred
> + to by the type_id.
> + - Otherwise, the tag applies to the struct or union member, or function
> + argument of the type referred to by type_id with the 0-based index
> + given by component_idx. */
> +struct btf_decl_tag
> +{
> + uint32_t component_idx;
> +};
> +
> +#define BTF_ENUM64_VALUE(ENUM64) \
> + ((int64_t) ((((uint64_t) (ENUM64)->val_hi32) << 32) | (ENUM64)->val_lo32))
> +
> +/* Type for callback to be passed to btf_map below.
> +
> + ABFD is the bfd containing the BTF section.
> + BUF is a pointer to the BTF section content.
> + STRTAB_OFFSET is the offset of the BTF string table in BUF.
> + TYPE_OFFSET is the offset of T in BUF.
> + TYPE_ID is the ID of the type being handled.
> + T is the type to be handled. */
> +
> +typedef void (*btf_type_map_cb) (bfd *abfd, bfd_byte *buf,
> + bfd_vma strtab_offset, bfd_vma type_offset,
> + uint32_t type_id, struct btf_type *entry);
> +
> +/* Iterate over the entries in a BTF section.
> +
> + ABFD is the bfd containing the BTF section.
> + SEC is the section containing BTF data.
> +
> + This function returns `false' if the section doesn't contain valid
> + BTF data or if there is an out of memory condition. */
> +
> +bool btf_map (bfd *abfd, asection *sec, btf_type_map_cb cb);
> +
> +/* Get the total size in bytes of a given BTF entry, including its
> + payload. */
> +
> +bfd_vma btf_type_size (struct btf_type *entry);
> +
> +/* Decoding functions. The functions returning pointers to structures
> + allocate memory, and it is up to the user to free that memory when
> + no longer used. */
> +
> +struct btf_header *btf_read_header (bfd *abfd, bfd_byte *buf);
> +struct btf_type *btf_read_type (bfd *abfd, bfd_byte *buf);
> +struct btf_member *btf_read_member (bfd *abfd, bfd_byte *buf);
> +struct btf_decl_tag *btf_read_decl_tag (bfd *abfd, bfd_byte *buf);
> +struct btf_var_secinfo *btf_read_var_secinfo (bfd *abfd, bfd_byte *buf);
> +struct btf_var *btf_read_var (bfd *abfd, bfd_byte *buf);
> +struct btf_param *btf_read_param (bfd *abfd, bfd_byte *buf);
> +struct btf_enum64 *btf_read_enum64 (bfd *abfd, bfd_byte *buf);
> +struct btf_enum *btf_read_enum (bfd *abdf, bfd_byte *buf);
> +struct btf_array *btf_read_array (bfd *abfd, bfd_byte *buf);
> +uint32_t btf_read_integral (bfd *abfd, bfd_byte *buf);
> +
> +#endif /* ! BTF_H */
More information about the Binutils
mailing list