[PATCH 1/2] bfd: add basic support for BTF debug info
David Faust
david.faust@oss.qualcomm.com
Wed Sep 30 18:22:08 GMT 2026
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 */
--
2.55.0
More information about the Binutils
mailing list