Compare commits

..

1 Commits

Author SHA1 Message Date
Thiago Marques
941f96ce0e add helpers to select kernel in some distributions 2021-10-19 20:17:09 +00:00
28 changed files with 716 additions and 1369 deletions

View File

@@ -1,40 +0,0 @@
---
# https://google.github.io/oss-fuzz/getting-started/continuous-integration/
name: CIFuzz
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
Fuzzing:
runs-on: ubuntu-latest
if: github.repository == 'libbpf/libbpf'
strategy:
fail-fast: false
matrix:
sanitizer: [address, undefined, memory]
steps:
- name: Build Fuzzers (${{ matrix.sanitizer }})
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'libbpf'
dry-run: false
allowed-broken-targets-percentage: 0
sanitizer: ${{ matrix.sanitizer }}
- name: Run Fuzzers (${{ matrix.sanitizer }})
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'libbpf'
fuzz-seconds: 300
dry-run: false
sanitizer: ${{ matrix.sanitizer }}
- name: Upload Crash
uses: actions/upload-artifact@v1
if: failure() && steps.build.outcome == 'success'
with:
name: ${{ matrix.sanitizer }}-artifacts
path: ./out/artifacts

View File

@@ -8,7 +8,6 @@ on:
jobs: jobs:
coverity: coverity:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository == 'libbpf/libbpf'
name: Coverity name: Coverity
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View File

@@ -1 +1 @@
47b3708c6088a60e7dc3b809dbb0d4c46590b32f 8d6c414cd2fb74aa6812e9bfec6178f8246c4f3a

View File

@@ -1 +1 @@
b8b5cb55f5d3f03cc1479a3768d68173a10359ad 5319255b8df9271474bc9027cabf82253934f28d

View File

@@ -19,11 +19,6 @@ the examples of building BPF applications with libbpf.
[libbpf-tools](https://github.com/iovisor/bcc/tree/master/libbpf-tools) are also [libbpf-tools](https://github.com/iovisor/bcc/tree/master/libbpf-tools) are also
a good source of the real-world libbpf-based tracing tools. a good source of the real-world libbpf-based tracing tools.
See also ["BPF CO-RE reference guide"](https://nakryiko.com/posts/bpf-core-reference-guide/)
for the coverage of practical aspects of building BPF CO-RE applications and
["BPF CO-RE"](https://nakryiko.com/posts/bpf-portability-and-co-re/) for
general introduction into BPF portability issues and BPF CO-RE origins.
All general BPF questions, including kernel functionality, libbpf APIs and All general BPF questions, including kernel functionality, libbpf APIs and
their application, should be sent to bpf@vger.kernel.org mailing list. You can their application, should be sent to bpf@vger.kernel.org mailing list. You can
subscribe to it [here](http://vger.kernel.org/vger-lists.html#bpf) and search subscribe to it [here](http://vger.kernel.org/vger-lists.html#bpf) and search
@@ -40,7 +35,6 @@ Build
[![Github Actions Builds & Tests](https://github.com/libbpf/libbpf/actions/workflows/test.yml/badge.svg)](https://github.com/libbpf/libbpf/actions/workflows/test.yml) [![Github Actions Builds & Tests](https://github.com/libbpf/libbpf/actions/workflows/test.yml/badge.svg)](https://github.com/libbpf/libbpf/actions/workflows/test.yml)
[![Total alerts](https://img.shields.io/lgtm/alerts/g/libbpf/libbpf.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/libbpf/libbpf/alerts/) [![Total alerts](https://img.shields.io/lgtm/alerts/g/libbpf/libbpf.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/libbpf/libbpf/alerts/)
[![Coverity](https://img.shields.io/coverity/scan/18195.svg)](https://scan.coverity.com/projects/libbpf) [![Coverity](https://img.shields.io/coverity/scan/18195.svg)](https://scan.coverity.com/projects/libbpf)
[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/libbpf.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html#libbpf)
===== =====
libelf is an internal dependency of libbpf and thus it is required to link libelf is an internal dependency of libbpf and thus it is required to link
against and must be installed on the system for applications to work. against and must be installed on the system for applications to work.
@@ -146,7 +140,6 @@ Otherwise, please make sure to update it on your system.
The following resources are useful to understand what BPF CO-RE is and how to The following resources are useful to understand what BPF CO-RE is and how to
use it: use it:
- [BPF CO-RE reference guide](https://nakryiko.com/posts/bpf-core-reference-guide/)
- [BPF Portability and CO-RE](https://nakryiko.com/posts/bpf-portability-and-co-re/) - [BPF Portability and CO-RE](https://nakryiko.com/posts/bpf-portability-and-co-re/)
- [HOWTO: BCC to libbpf conversion](https://nakryiko.com/posts/bcc-to-libbpf-howto-guide/) - [HOWTO: BCC to libbpf conversion](https://nakryiko.com/posts/bcc-to-libbpf-howto-guide/)
- [libbpf-tools in BCC repo](https://github.com/iovisor/bcc/tree/master/libbpf-tools) - [libbpf-tools in BCC repo](https://github.com/iovisor/bcc/tree/master/libbpf-tools)

View File

@@ -13,14 +13,6 @@
.off = OFF, \ .off = OFF, \
.imm = IMM }) .imm = IMM })
#define BPF_ALU32_IMM(OP, DST, IMM) \
((struct bpf_insn) { \
.code = BPF_ALU | BPF_OP(OP) | BPF_K, \
.dst_reg = DST, \
.src_reg = 0, \
.off = 0, \
.imm = IMM })
#define BPF_ALU64_IMM(OP, DST, IMM) \ #define BPF_ALU64_IMM(OP, DST, IMM) \
((struct bpf_insn) { \ ((struct bpf_insn) { \
.code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \ .code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \

View File

@@ -906,7 +906,6 @@ enum bpf_map_type {
BPF_MAP_TYPE_RINGBUF, BPF_MAP_TYPE_RINGBUF,
BPF_MAP_TYPE_INODE_STORAGE, BPF_MAP_TYPE_INODE_STORAGE,
BPF_MAP_TYPE_TASK_STORAGE, BPF_MAP_TYPE_TASK_STORAGE,
BPF_MAP_TYPE_BLOOM_FILTER,
}; };
/* Note that tracing related programs such as /* Note that tracing related programs such as
@@ -1275,13 +1274,6 @@ union bpf_attr {
* struct stored as the * struct stored as the
* map value * map value
*/ */
/* Any per-map-type extra fields
*
* BPF_MAP_TYPE_BLOOM_FILTER - the lowest 4 bits indicate the
* number of hash functions (if 0, the bloom filter will default
* to using 5 hash functions).
*/
__u64 map_extra;
}; };
struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */ struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
@@ -4917,27 +4909,6 @@ union bpf_attr {
* Return * Return
* The number of bytes written to the buffer, or a negative error * The number of bytes written to the buffer, or a negative error
* in case of failure. * in case of failure.
*
* struct unix_sock *bpf_skc_to_unix_sock(void *sk)
* Description
* Dynamically cast a *sk* pointer to a *unix_sock* pointer.
* Return
* *sk* if casting is valid, or **NULL** otherwise.
*
* long bpf_kallsyms_lookup_name(const char *name, int name_sz, int flags, u64 *res)
* Description
* Get the address of a kernel symbol, returned in *res*. *res* is
* set to 0 if the symbol is not found.
* Return
* On success, zero. On error, a negative value.
*
* **-EINVAL** if *flags* is not zero.
*
* **-EINVAL** if string *name* is not the same size as *name_sz*.
*
* **-ENOENT** if symbol is not found.
*
* **-EPERM** if caller does not have permission to obtain kernel address.
*/ */
#define __BPF_FUNC_MAPPER(FN) \ #define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \ FN(unspec), \
@@ -5118,8 +5089,6 @@ union bpf_attr {
FN(task_pt_regs), \ FN(task_pt_regs), \
FN(get_branch_snapshot), \ FN(get_branch_snapshot), \
FN(trace_vprintk), \ FN(trace_vprintk), \
FN(skc_to_unix_sock), \
FN(kallsyms_lookup_name), \
/* */ /* */
/* integer value in 'imm' field of BPF_CALL instruction selects which helper /* integer value in 'imm' field of BPF_CALL instruction selects which helper
@@ -5644,7 +5613,6 @@ struct bpf_prog_info {
__u64 run_time_ns; __u64 run_time_ns;
__u64 run_cnt; __u64 run_cnt;
__u64 recursion_misses; __u64 recursion_misses;
__u32 verified_insns;
} __attribute__((aligned(8))); } __attribute__((aligned(8)));
struct bpf_map_info { struct bpf_map_info {
@@ -5662,8 +5630,6 @@ struct bpf_map_info {
__u32 btf_id; __u32 btf_id;
__u32 btf_key_type_id; __u32 btf_key_type_id;
__u32 btf_value_type_id; __u32 btf_value_type_id;
__u32 :32; /* alignment pad */
__u64 map_extra;
} __attribute__((aligned(8))); } __attribute__((aligned(8)));
struct bpf_btf_info { struct bpf_btf_info {

View File

@@ -43,7 +43,7 @@ struct btf_type {
* "size" tells the size of the type it is describing. * "size" tells the size of the type it is describing.
* *
* "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT, * "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
* FUNC, FUNC_PROTO, VAR and DECL_TAG. * FUNC, FUNC_PROTO, VAR and TAG.
* "type" is a type_id referring to another type. * "type" is a type_id referring to another type.
*/ */
union { union {
@@ -74,7 +74,7 @@ enum {
BTF_KIND_VAR = 14, /* Variable */ BTF_KIND_VAR = 14, /* Variable */
BTF_KIND_DATASEC = 15, /* Section */ BTF_KIND_DATASEC = 15, /* Section */
BTF_KIND_FLOAT = 16, /* Floating point */ BTF_KIND_FLOAT = 16, /* Floating point */
BTF_KIND_DECL_TAG = 17, /* Decl Tag */ BTF_KIND_TAG = 17, /* Tag */
NR_BTF_KINDS, NR_BTF_KINDS,
BTF_KIND_MAX = NR_BTF_KINDS - 1, BTF_KIND_MAX = NR_BTF_KINDS - 1,
@@ -174,14 +174,14 @@ struct btf_var_secinfo {
__u32 size; __u32 size;
}; };
/* BTF_KIND_DECL_TAG is followed by a single "struct btf_decl_tag" to describe /* BTF_KIND_TAG is followed by a single "struct btf_tag" to describe
* additional information related to the tag applied location. * additional information related to the tag applied location.
* If component_idx == -1, the tag is applied to a struct, union, * If component_idx == -1, the tag is applied to a struct, union,
* variable or function. Otherwise, it is applied to a struct/union * variable or function. Otherwise, it is applied to a struct/union
* member or a func argument, and component_idx indicates which member * member or a func argument, and component_idx indicates which member
* or argument (0 ... vlen-1). * or argument (0 ... vlen-1).
*/ */
struct btf_decl_tag { struct btf_tag {
__s32 component_idx; __s32 component_idx;
}; };

View File

@@ -17,7 +17,7 @@ BPF_BRANCH=${3-""}
BASELINE_COMMIT=${BPF_NEXT_BASELINE:-$(cat ${LIBBPF_REPO}/CHECKPOINT-COMMIT)} BASELINE_COMMIT=${BPF_NEXT_BASELINE:-$(cat ${LIBBPF_REPO}/CHECKPOINT-COMMIT)}
BPF_BASELINE_COMMIT=${BPF_BASELINE:-$(cat ${LIBBPF_REPO}/BPF-CHECKPOINT-COMMIT)} BPF_BASELINE_COMMIT=${BPF_BASELINE:-$(cat ${LIBBPF_REPO}/BPF-CHECKPOINT-COMMIT)}
if [ -z "${LIBBPF_REPO}" ] || [ -z "${LINUX_REPO}" ]; then if [ -z "${LIBBPF_REPO}" ] || [ -z "${LINUX_REPO}" ] || [ -z "${BPF_BRANCH}" ]; then
echo "Error: libbpf or linux repos are not specified" echo "Error: libbpf or linux repos are not specified"
usage usage
fi fi
@@ -74,7 +74,7 @@ commit_desc()
} }
# Create commit single-line signature, which consists of: # Create commit single-line signature, which consists of:
# - full commit subject # - full commit hash
# - author date in ISO8601 format # - author date in ISO8601 format
# - full commit body with newlines replaced with vertical bars (|) # - full commit body with newlines replaced with vertical bars (|)
# - shortstat appended at the end # - shortstat appended at the end

View File

@@ -65,28 +65,19 @@ static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
return syscall(__NR_bpf, cmd, attr, size); return syscall(__NR_bpf, cmd, attr, size);
} }
static inline int sys_bpf_fd(enum bpf_cmd cmd, union bpf_attr *attr,
unsigned int size)
{
int fd;
fd = sys_bpf(cmd, attr, size);
return ensure_good_fd(fd);
}
static inline int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size) static inline int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size)
{ {
int retries = 5; int retries = 5;
int fd; int fd;
do { do {
fd = sys_bpf_fd(BPF_PROG_LOAD, attr, size); fd = sys_bpf(BPF_PROG_LOAD, attr, size);
} while (fd < 0 && errno == EAGAIN && retries-- > 0); } while (fd < 0 && errno == EAGAIN && retries-- > 0);
return fd; return fd;
} }
int libbpf__bpf_create_map_xattr(const struct bpf_create_map_params *create_attr) int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr)
{ {
union bpf_attr attr; union bpf_attr attr;
int fd; int fd;
@@ -111,36 +102,11 @@ int libbpf__bpf_create_map_xattr(const struct bpf_create_map_params *create_attr
create_attr->btf_vmlinux_value_type_id; create_attr->btf_vmlinux_value_type_id;
else else
attr.inner_map_fd = create_attr->inner_map_fd; attr.inner_map_fd = create_attr->inner_map_fd;
attr.map_extra = create_attr->map_extra;
fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, sizeof(attr)); fd = sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
return libbpf_err_errno(fd); return libbpf_err_errno(fd);
} }
int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr)
{
struct bpf_create_map_params p = {};
p.map_type = create_attr->map_type;
p.key_size = create_attr->key_size;
p.value_size = create_attr->value_size;
p.max_entries = create_attr->max_entries;
p.map_flags = create_attr->map_flags;
p.name = create_attr->name;
p.numa_node = create_attr->numa_node;
p.btf_fd = create_attr->btf_fd;
p.btf_key_type_id = create_attr->btf_key_type_id;
p.btf_value_type_id = create_attr->btf_value_type_id;
p.map_ifindex = create_attr->map_ifindex;
if (p.map_type == BPF_MAP_TYPE_STRUCT_OPS)
p.btf_vmlinux_value_type_id =
create_attr->btf_vmlinux_value_type_id;
else
p.inner_map_fd = create_attr->inner_map_fd;
return libbpf__bpf_create_map_xattr(&p);
}
int bpf_create_map_node(enum bpf_map_type map_type, const char *name, int bpf_create_map_node(enum bpf_map_type map_type, const char *name,
int key_size, int value_size, int max_entries, int key_size, int value_size, int max_entries,
__u32 map_flags, int node) __u32 map_flags, int node)
@@ -215,7 +181,7 @@ int bpf_create_map_in_map_node(enum bpf_map_type map_type, const char *name,
attr.numa_node = node; attr.numa_node = node;
} }
fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, sizeof(attr)); fd = sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
return libbpf_err_errno(fd); return libbpf_err_errno(fd);
} }
@@ -515,7 +481,6 @@ int bpf_map_lookup_and_delete_elem(int fd, const void *key, void *value)
int bpf_map_lookup_and_delete_elem_flags(int fd, const void *key, void *value, __u64 flags) int bpf_map_lookup_and_delete_elem_flags(int fd, const void *key, void *value, __u64 flags)
{ {
union bpf_attr attr; union bpf_attr attr;
int ret;
memset(&attr, 0, sizeof(attr)); memset(&attr, 0, sizeof(attr));
attr.map_fd = fd; attr.map_fd = fd;
@@ -523,8 +488,7 @@ int bpf_map_lookup_and_delete_elem_flags(int fd, const void *key, void *value, _
attr.value = ptr_to_u64(value); attr.value = ptr_to_u64(value);
attr.flags = flags; attr.flags = flags;
ret = sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM, &attr, sizeof(attr)); return sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM, &attr, sizeof(attr));
return libbpf_err_errno(ret);
} }
int bpf_map_delete_elem(int fd, const void *key) int bpf_map_delete_elem(int fd, const void *key)
@@ -645,7 +609,7 @@ int bpf_obj_get(const char *pathname)
memset(&attr, 0, sizeof(attr)); memset(&attr, 0, sizeof(attr));
attr.pathname = ptr_to_u64((void *)pathname); attr.pathname = ptr_to_u64((void *)pathname);
fd = sys_bpf_fd(BPF_OBJ_GET, &attr, sizeof(attr)); fd = sys_bpf(BPF_OBJ_GET, &attr, sizeof(attr));
return libbpf_err_errno(fd); return libbpf_err_errno(fd);
} }
@@ -756,7 +720,7 @@ int bpf_link_create(int prog_fd, int target_fd,
break; break;
} }
proceed: proceed:
fd = sys_bpf_fd(BPF_LINK_CREATE, &attr, sizeof(attr)); fd = sys_bpf(BPF_LINK_CREATE, &attr, sizeof(attr));
return libbpf_err_errno(fd); return libbpf_err_errno(fd);
} }
@@ -799,7 +763,7 @@ int bpf_iter_create(int link_fd)
memset(&attr, 0, sizeof(attr)); memset(&attr, 0, sizeof(attr));
attr.iter_create.link_fd = link_fd; attr.iter_create.link_fd = link_fd;
fd = sys_bpf_fd(BPF_ITER_CREATE, &attr, sizeof(attr)); fd = sys_bpf(BPF_ITER_CREATE, &attr, sizeof(attr));
return libbpf_err_errno(fd); return libbpf_err_errno(fd);
} }
@@ -957,7 +921,7 @@ int bpf_prog_get_fd_by_id(__u32 id)
memset(&attr, 0, sizeof(attr)); memset(&attr, 0, sizeof(attr));
attr.prog_id = id; attr.prog_id = id;
fd = sys_bpf_fd(BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr)); fd = sys_bpf(BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr));
return libbpf_err_errno(fd); return libbpf_err_errno(fd);
} }
@@ -969,7 +933,7 @@ int bpf_map_get_fd_by_id(__u32 id)
memset(&attr, 0, sizeof(attr)); memset(&attr, 0, sizeof(attr));
attr.map_id = id; attr.map_id = id;
fd = sys_bpf_fd(BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr)); fd = sys_bpf(BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr));
return libbpf_err_errno(fd); return libbpf_err_errno(fd);
} }
@@ -981,7 +945,7 @@ int bpf_btf_get_fd_by_id(__u32 id)
memset(&attr, 0, sizeof(attr)); memset(&attr, 0, sizeof(attr));
attr.btf_id = id; attr.btf_id = id;
fd = sys_bpf_fd(BPF_BTF_GET_FD_BY_ID, &attr, sizeof(attr)); fd = sys_bpf(BPF_BTF_GET_FD_BY_ID, &attr, sizeof(attr));
return libbpf_err_errno(fd); return libbpf_err_errno(fd);
} }
@@ -993,7 +957,7 @@ int bpf_link_get_fd_by_id(__u32 id)
memset(&attr, 0, sizeof(attr)); memset(&attr, 0, sizeof(attr));
attr.link_id = id; attr.link_id = id;
fd = sys_bpf_fd(BPF_LINK_GET_FD_BY_ID, &attr, sizeof(attr)); fd = sys_bpf(BPF_LINK_GET_FD_BY_ID, &attr, sizeof(attr));
return libbpf_err_errno(fd); return libbpf_err_errno(fd);
} }
@@ -1024,7 +988,7 @@ int bpf_raw_tracepoint_open(const char *name, int prog_fd)
attr.raw_tracepoint.name = ptr_to_u64(name); attr.raw_tracepoint.name = ptr_to_u64(name);
attr.raw_tracepoint.prog_fd = prog_fd; attr.raw_tracepoint.prog_fd = prog_fd;
fd = sys_bpf_fd(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr)); fd = sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr));
return libbpf_err_errno(fd); return libbpf_err_errno(fd);
} }
@@ -1044,7 +1008,7 @@ retry:
attr.btf_log_buf = ptr_to_u64(log_buf); attr.btf_log_buf = ptr_to_u64(log_buf);
} }
fd = sys_bpf_fd(BPF_BTF_LOAD, &attr, sizeof(attr)); fd = sys_bpf(BPF_BTF_LOAD, &attr, sizeof(attr));
if (fd < 0 && !do_log && log_buf && log_buf_size) { if (fd < 0 && !do_log && log_buf && log_buf_size) {
do_log = true; do_log = true;
@@ -1086,7 +1050,7 @@ int bpf_enable_stats(enum bpf_stats_type type)
memset(&attr, 0, sizeof(attr)); memset(&attr, 0, sizeof(attr));
attr.enable_stats.type = type; attr.enable_stats.type = type;
fd = sys_bpf_fd(BPF_ENABLE_STATS, &attr, sizeof(attr)); fd = sys_bpf(BPF_ENABLE_STATS, &attr, sizeof(attr));
return libbpf_err_errno(fd); return libbpf_err_errno(fd);
} }

View File

@@ -40,7 +40,7 @@ enum bpf_enum_value_kind {
#define __CORE_RELO(src, field, info) \ #define __CORE_RELO(src, field, info) \
__builtin_preserve_field_info((src)->field, BPF_FIELD_##info) __builtin_preserve_field_info((src)->field, BPF_FIELD_##info)
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #if __BYTE_ORDER == __LITTLE_ENDIAN
#define __CORE_BITFIELD_PROBE_READ(dst, src, fld) \ #define __CORE_BITFIELD_PROBE_READ(dst, src, fld) \
bpf_probe_read_kernel( \ bpf_probe_read_kernel( \
(void *)dst, \ (void *)dst, \

View File

@@ -8,19 +8,13 @@ struct ksym_relo_desc {
int kind; int kind;
int insn_idx; int insn_idx;
bool is_weak; bool is_weak;
bool is_typeless;
}; };
struct ksym_desc { struct ksym_desc {
const char *name; const char *name;
int ref; int ref;
int kind; int kind;
union { int off;
/* used for kfunc */
int off;
/* used for typeless ksym */
bool typeless;
};
int insn; int insn;
}; };
@@ -49,13 +43,13 @@ void bpf_gen__init(struct bpf_gen *gen, int log_level);
int bpf_gen__finish(struct bpf_gen *gen); int bpf_gen__finish(struct bpf_gen *gen);
void bpf_gen__free(struct bpf_gen *gen); void bpf_gen__free(struct bpf_gen *gen);
void bpf_gen__load_btf(struct bpf_gen *gen, const void *raw_data, __u32 raw_size); void bpf_gen__load_btf(struct bpf_gen *gen, const void *raw_data, __u32 raw_size);
void bpf_gen__map_create(struct bpf_gen *gen, struct bpf_create_map_params *map_attr, int map_idx); void bpf_gen__map_create(struct bpf_gen *gen, struct bpf_create_map_attr *map_attr, int map_idx);
struct bpf_prog_load_params; struct bpf_prog_load_params;
void bpf_gen__prog_load(struct bpf_gen *gen, struct bpf_prog_load_params *load_attr, int prog_idx); void bpf_gen__prog_load(struct bpf_gen *gen, struct bpf_prog_load_params *load_attr, int prog_idx);
void bpf_gen__map_update_elem(struct bpf_gen *gen, int map_idx, void *value, __u32 value_size); void bpf_gen__map_update_elem(struct bpf_gen *gen, int map_idx, void *value, __u32 value_size);
void bpf_gen__map_freeze(struct bpf_gen *gen, int map_idx); void bpf_gen__map_freeze(struct bpf_gen *gen, int map_idx);
void bpf_gen__record_attach_target(struct bpf_gen *gen, const char *name, enum bpf_attach_type type); void bpf_gen__record_attach_target(struct bpf_gen *gen, const char *name, enum bpf_attach_type type);
void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, bool is_weak, void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, bool is_weak, int kind,
bool is_typeless, int kind, int insn_idx); int insn_idx);
#endif #endif

View File

@@ -27,7 +27,6 @@ struct tcp_sock;
struct tcp_timewait_sock; struct tcp_timewait_sock;
struct tcp_request_sock; struct tcp_request_sock;
struct udp6_sock; struct udp6_sock;
struct unix_sock;
struct task_struct; struct task_struct;
struct __sk_buff; struct __sk_buff;
struct sk_msg_md; struct sk_msg_md;
@@ -4084,33 +4083,4 @@ static long (*bpf_get_branch_snapshot)(void *entries, __u32 size, __u64 flags) =
*/ */
static long (*bpf_trace_vprintk)(const char *fmt, __u32 fmt_size, const void *data, __u32 data_len) = (void *) 177; static long (*bpf_trace_vprintk)(const char *fmt, __u32 fmt_size, const void *data, __u32 data_len) = (void *) 177;
/*
* bpf_skc_to_unix_sock
*
* Dynamically cast a *sk* pointer to a *unix_sock* pointer.
*
* Returns
* *sk* if casting is valid, or **NULL** otherwise.
*/
static struct unix_sock *(*bpf_skc_to_unix_sock)(void *sk) = (void *) 178;
/*
* bpf_kallsyms_lookup_name
*
* Get the address of a kernel symbol, returned in *res*. *res* is
* set to 0 if the symbol is not found.
*
* Returns
* On success, zero. On error, a negative value.
*
* **-EINVAL** if *flags* is not zero.
*
* **-EINVAL** if string *name* is not the same size as *name_sz*.
*
* **-ENOENT** if symbol is not found.
*
* **-EPERM** if caller does not have permission to obtain kernel address.
*/
static long (*bpf_kallsyms_lookup_name)(const char *name, int name_sz, int flags, __u64 *res) = (void *) 179;

View File

@@ -24,9 +24,6 @@
#elif defined(__TARGET_ARCH_sparc) #elif defined(__TARGET_ARCH_sparc)
#define bpf_target_sparc #define bpf_target_sparc
#define bpf_target_defined #define bpf_target_defined
#elif defined(__TARGET_ARCH_riscv)
#define bpf_target_riscv
#define bpf_target_defined
#else #else
/* Fall back to what the compiler says */ /* Fall back to what the compiler says */
@@ -51,9 +48,6 @@
#elif defined(__sparc__) #elif defined(__sparc__)
#define bpf_target_sparc #define bpf_target_sparc
#define bpf_target_defined #define bpf_target_defined
#elif defined(__riscv) && __riscv_xlen == 64
#define bpf_target_riscv
#define bpf_target_defined
#endif /* no compiler target */ #endif /* no compiler target */
#endif #endif
@@ -294,32 +288,6 @@ struct pt_regs;
#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), pc) #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), pc)
#endif #endif
#elif defined(bpf_target_riscv)
struct pt_regs;
#define PT_REGS_RV const volatile struct user_regs_struct
#define PT_REGS_PARM1(x) (((PT_REGS_RV *)(x))->a0)
#define PT_REGS_PARM2(x) (((PT_REGS_RV *)(x))->a1)
#define PT_REGS_PARM3(x) (((PT_REGS_RV *)(x))->a2)
#define PT_REGS_PARM4(x) (((PT_REGS_RV *)(x))->a3)
#define PT_REGS_PARM5(x) (((PT_REGS_RV *)(x))->a4)
#define PT_REGS_RET(x) (((PT_REGS_RV *)(x))->ra)
#define PT_REGS_FP(x) (((PT_REGS_RV *)(x))->s5)
#define PT_REGS_RC(x) (((PT_REGS_RV *)(x))->a5)
#define PT_REGS_SP(x) (((PT_REGS_RV *)(x))->sp)
#define PT_REGS_IP(x) (((PT_REGS_RV *)(x))->epc)
#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a0)
#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a1)
#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a2)
#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a3)
#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a4)
#define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), ra)
#define PT_REGS_FP_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), fp)
#define PT_REGS_RC_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a5)
#define PT_REGS_SP_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), sp)
#define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), epc)
#endif #endif
#if defined(bpf_target_powerpc) #if defined(bpf_target_powerpc)

193
src/btf.c
View File

@@ -57,7 +57,7 @@ struct btf {
* representation is broken up into three independently allocated * representation is broken up into three independently allocated
* memory regions to be able to modify them independently. * memory regions to be able to modify them independently.
* raw_data is nulled out at that point, but can be later allocated * raw_data is nulled out at that point, but can be later allocated
* and cached again if user calls btf__raw_data(), at which point * and cached again if user calls btf__get_raw_data(), at which point
* raw_data will contain a contiguous copy of header, types, and * raw_data will contain a contiguous copy of header, types, and
* strings: * strings:
* *
@@ -236,23 +236,17 @@ static int btf_parse_hdr(struct btf *btf)
} }
btf_bswap_hdr(hdr); btf_bswap_hdr(hdr);
} else if (hdr->magic != BTF_MAGIC) { } else if (hdr->magic != BTF_MAGIC) {
pr_debug("Invalid BTF magic: %x\n", hdr->magic); pr_debug("Invalid BTF magic:%x\n", hdr->magic);
return -EINVAL; return -EINVAL;
} }
if (btf->raw_size < hdr->hdr_len) { meta_left = btf->raw_size - sizeof(*hdr);
pr_debug("BTF header len %u larger than data size %u\n", if (meta_left < hdr->str_off + hdr->str_len) {
hdr->hdr_len, btf->raw_size); pr_debug("Invalid BTF total size:%u\n", btf->raw_size);
return -EINVAL; return -EINVAL;
} }
meta_left = btf->raw_size - hdr->hdr_len; if (hdr->type_off + hdr->type_len > hdr->str_off) {
if (meta_left < (long long)hdr->str_off + hdr->str_len) {
pr_debug("Invalid BTF total size: %u\n", btf->raw_size);
return -EINVAL;
}
if ((long long)hdr->type_off + hdr->type_len > hdr->str_off) {
pr_debug("Invalid BTF data sections layout: type data at %u + %u, strings data at %u + %u\n", pr_debug("Invalid BTF data sections layout: type data at %u + %u, strings data at %u + %u\n",
hdr->type_off, hdr->type_len, hdr->str_off, hdr->str_len); hdr->type_off, hdr->type_len, hdr->str_off, hdr->str_len);
return -EINVAL; return -EINVAL;
@@ -315,8 +309,8 @@ static int btf_type_size(const struct btf_type *t)
return base_size + sizeof(struct btf_var); return base_size + sizeof(struct btf_var);
case BTF_KIND_DATASEC: case BTF_KIND_DATASEC:
return base_size + vlen * sizeof(struct btf_var_secinfo); return base_size + vlen * sizeof(struct btf_var_secinfo);
case BTF_KIND_DECL_TAG: case BTF_KIND_TAG:
return base_size + sizeof(struct btf_decl_tag); return base_size + sizeof(struct btf_tag);
default: default:
pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t)); pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t));
return -EINVAL; return -EINVAL;
@@ -389,8 +383,8 @@ static int btf_bswap_type_rest(struct btf_type *t)
v->size = bswap_32(v->size); v->size = bswap_32(v->size);
} }
return 0; return 0;
case BTF_KIND_DECL_TAG: case BTF_KIND_TAG:
btf_decl_tag(t)->component_idx = bswap_32(btf_decl_tag(t)->component_idx); btf_tag(t)->component_idx = bswap_32(btf_tag(t)->component_idx);
return 0; return 0;
default: default:
pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t)); pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t));
@@ -441,11 +435,6 @@ __u32 btf__get_nr_types(const struct btf *btf)
return btf->start_id + btf->nr_types - 1; return btf->start_id + btf->nr_types - 1;
} }
__u32 btf__type_cnt(const struct btf *btf)
{
return btf->start_id + btf->nr_types;
}
const struct btf *btf__base_btf(const struct btf *btf) const struct btf *btf__base_btf(const struct btf *btf)
{ {
return btf->base_btf; return btf->base_btf;
@@ -477,8 +466,8 @@ static int determine_ptr_size(const struct btf *btf)
if (btf->base_btf && btf->base_btf->ptr_sz > 0) if (btf->base_btf && btf->base_btf->ptr_sz > 0)
return btf->base_btf->ptr_sz; return btf->base_btf->ptr_sz;
n = btf__type_cnt(btf); n = btf__get_nr_types(btf);
for (i = 1; i < n; i++) { for (i = 1; i <= n; i++) {
t = btf__type_by_id(btf, i); t = btf__type_by_id(btf, i);
if (!btf_is_int(t)) if (!btf_is_int(t))
continue; continue;
@@ -538,9 +527,9 @@ int btf__set_pointer_size(struct btf *btf, size_t ptr_sz)
static bool is_host_big_endian(void) static bool is_host_big_endian(void)
{ {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #if __BYTE_ORDER == __LITTLE_ENDIAN
return false; return false;
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #elif __BYTE_ORDER == __BIG_ENDIAN
return true; return true;
#else #else
# error "Unrecognized __BYTE_ORDER__" # error "Unrecognized __BYTE_ORDER__"
@@ -607,7 +596,7 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
case BTF_KIND_CONST: case BTF_KIND_CONST:
case BTF_KIND_RESTRICT: case BTF_KIND_RESTRICT:
case BTF_KIND_VAR: case BTF_KIND_VAR:
case BTF_KIND_DECL_TAG: case BTF_KIND_TAG:
type_id = t->type; type_id = t->type;
break; break;
case BTF_KIND_ARRAY: case BTF_KIND_ARRAY:
@@ -695,12 +684,12 @@ int btf__resolve_type(const struct btf *btf, __u32 type_id)
__s32 btf__find_by_name(const struct btf *btf, const char *type_name) __s32 btf__find_by_name(const struct btf *btf, const char *type_name)
{ {
__u32 i, nr_types = btf__type_cnt(btf); __u32 i, nr_types = btf__get_nr_types(btf);
if (!strcmp(type_name, "void")) if (!strcmp(type_name, "void"))
return 0; return 0;
for (i = 1; i < nr_types; i++) { for (i = 1; i <= nr_types; i++) {
const struct btf_type *t = btf__type_by_id(btf, i); const struct btf_type *t = btf__type_by_id(btf, i);
const char *name = btf__name_by_offset(btf, t->name_off); const char *name = btf__name_by_offset(btf, t->name_off);
@@ -714,12 +703,12 @@ __s32 btf__find_by_name(const struct btf *btf, const char *type_name)
static __s32 btf_find_by_name_kind(const struct btf *btf, int start_id, static __s32 btf_find_by_name_kind(const struct btf *btf, int start_id,
const char *type_name, __u32 kind) const char *type_name, __u32 kind)
{ {
__u32 i, nr_types = btf__type_cnt(btf); __u32 i, nr_types = btf__get_nr_types(btf);
if (kind == BTF_KIND_UNKN || !strcmp(type_name, "void")) if (kind == BTF_KIND_UNKN || !strcmp(type_name, "void"))
return 0; return 0;
for (i = start_id; i < nr_types; i++) { for (i = start_id; i <= nr_types; i++) {
const struct btf_type *t = btf__type_by_id(btf, i); const struct btf_type *t = btf__type_by_id(btf, i);
const char *name; const char *name;
@@ -792,7 +781,7 @@ static struct btf *btf_new_empty(struct btf *base_btf)
if (base_btf) { if (base_btf) {
btf->base_btf = base_btf; btf->base_btf = base_btf;
btf->start_id = btf__type_cnt(base_btf); btf->start_id = btf__get_nr_types(base_btf) + 1;
btf->start_str_off = base_btf->hdr->str_len; btf->start_str_off = base_btf->hdr->str_len;
} }
@@ -842,7 +831,7 @@ static struct btf *btf_new(const void *data, __u32 size, struct btf *base_btf)
if (base_btf) { if (base_btf) {
btf->base_btf = base_btf; btf->base_btf = base_btf;
btf->start_id = btf__type_cnt(base_btf); btf->start_id = btf__get_nr_types(base_btf) + 1;
btf->start_str_off = base_btf->hdr->str_len; btf->start_str_off = base_btf->hdr->str_len;
} }
@@ -897,7 +886,7 @@ static struct btf *btf_parse_elf(const char *path, struct btf *base_btf,
return ERR_PTR(-LIBBPF_ERRNO__LIBELF); return ERR_PTR(-LIBBPF_ERRNO__LIBELF);
} }
fd = open(path, O_RDONLY | O_CLOEXEC); fd = open(path, O_RDONLY);
if (fd < 0) { if (fd < 0) {
err = -errno; err = -errno;
pr_warn("failed to open %s: %s\n", path, strerror(errno)); pr_warn("failed to open %s: %s\n", path, strerror(errno));
@@ -1118,6 +1107,99 @@ struct btf *btf__parse_split(const char *path, struct btf *base_btf)
return libbpf_ptr(btf_parse(path, base_btf, NULL)); return libbpf_ptr(btf_parse(path, base_btf, NULL));
} }
static int compare_vsi_off(const void *_a, const void *_b)
{
const struct btf_var_secinfo *a = _a;
const struct btf_var_secinfo *b = _b;
return a->offset - b->offset;
}
static int btf_fixup_datasec(struct bpf_object *obj, struct btf *btf,
struct btf_type *t)
{
__u32 size = 0, off = 0, i, vars = btf_vlen(t);
const char *name = btf__name_by_offset(btf, t->name_off);
const struct btf_type *t_var;
struct btf_var_secinfo *vsi;
const struct btf_var *var;
int ret;
if (!name) {
pr_debug("No name found in string section for DATASEC kind.\n");
return -ENOENT;
}
/* .extern datasec size and var offsets were set correctly during
* extern collection step, so just skip straight to sorting variables
*/
if (t->size)
goto sort_vars;
ret = bpf_object__section_size(obj, name, &size);
if (ret || !size || (t->size && t->size != size)) {
pr_debug("Invalid size for section %s: %u bytes\n", name, size);
return -ENOENT;
}
t->size = size;
for (i = 0, vsi = btf_var_secinfos(t); i < vars; i++, vsi++) {
t_var = btf__type_by_id(btf, vsi->type);
var = btf_var(t_var);
if (!btf_is_var(t_var)) {
pr_debug("Non-VAR type seen in section %s\n", name);
return -EINVAL;
}
if (var->linkage == BTF_VAR_STATIC)
continue;
name = btf__name_by_offset(btf, t_var->name_off);
if (!name) {
pr_debug("No name found in string section for VAR kind\n");
return -ENOENT;
}
ret = bpf_object__variable_offset(obj, name, &off);
if (ret) {
pr_debug("No offset found in symbol table for VAR %s\n",
name);
return -ENOENT;
}
vsi->offset = off;
}
sort_vars:
qsort(btf_var_secinfos(t), vars, sizeof(*vsi), compare_vsi_off);
return 0;
}
int btf__finalize_data(struct bpf_object *obj, struct btf *btf)
{
int err = 0;
__u32 i;
for (i = 1; i <= btf->nr_types; i++) {
struct btf_type *t = btf_type_by_id(btf, i);
/* Loader needs to fix up some of the things compiler
* couldn't get its hands on while emitting BTF. This
* is section size and global variable offset. We use
* the info from the ELF itself for this purpose.
*/
if (btf_is_datasec(t)) {
err = btf_fixup_datasec(obj, btf, t);
if (err)
break;
}
}
return libbpf_err(err);
}
static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endian); static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endian);
int btf__load_into_kernel(struct btf *btf) int btf__load_into_kernel(struct btf *btf)
@@ -1235,7 +1317,7 @@ err_out:
return NULL; return NULL;
} }
const void *btf__raw_data(const struct btf *btf_ro, __u32 *size) const void *btf__get_raw_data(const struct btf *btf_ro, __u32 *size)
{ {
struct btf *btf = (struct btf *)btf_ro; struct btf *btf = (struct btf *)btf_ro;
__u32 data_sz; __u32 data_sz;
@@ -1243,7 +1325,7 @@ const void *btf__raw_data(const struct btf *btf_ro, __u32 *size)
data = btf_get_raw_data(btf, &data_sz, btf->swapped_endian); data = btf_get_raw_data(btf, &data_sz, btf->swapped_endian);
if (!data) if (!data)
return errno = ENOMEM, NULL; return errno = -ENOMEM, NULL;
btf->raw_size = data_sz; btf->raw_size = data_sz;
if (btf->swapped_endian) if (btf->swapped_endian)
@@ -1254,9 +1336,6 @@ const void *btf__raw_data(const struct btf *btf_ro, __u32 *size)
return data; return data;
} }
__attribute__((alias("btf__raw_data")))
const void *btf__get_raw_data(const struct btf *btf, __u32 *size);
const char *btf__str_by_offset(const struct btf *btf, __u32 offset) const char *btf__str_by_offset(const struct btf *btf, __u32 offset)
{ {
if (offset < btf->start_str_off) if (offset < btf->start_str_off)
@@ -1665,7 +1744,7 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf)
old_strs_len = btf->hdr->str_len; old_strs_len = btf->hdr->str_len;
data_sz = src_btf->hdr->type_len; data_sz = src_btf->hdr->type_len;
cnt = btf__type_cnt(src_btf) - 1; cnt = btf__get_nr_types(src_btf);
/* pre-allocate enough memory for new types */ /* pre-allocate enough memory for new types */
t = btf_add_type_mem(btf, data_sz); t = btf_add_type_mem(btf, data_sz);
@@ -1982,7 +2061,7 @@ int btf__add_union(struct btf *btf, const char *name, __u32 byte_sz)
static struct btf_type *btf_last_type(struct btf *btf) static struct btf_type *btf_last_type(struct btf *btf)
{ {
return btf_type_by_id(btf, btf__type_cnt(btf) - 1); return btf_type_by_id(btf, btf__get_nr_types(btf));
} }
/* /*
@@ -2490,7 +2569,7 @@ int btf__add_datasec_var_info(struct btf *btf, int var_type_id, __u32 offset, __
} }
/* /*
* Append new BTF_KIND_DECL_TAG type with: * Append new BTF_KIND_TAG type with:
* - *value* - non-empty/non-NULL string; * - *value* - non-empty/non-NULL string;
* - *ref_type_id* - referenced type ID, it might not exist yet; * - *ref_type_id* - referenced type ID, it might not exist yet;
* - *component_idx* - -1 for tagging reference type, otherwise struct/union * - *component_idx* - -1 for tagging reference type, otherwise struct/union
@@ -2499,7 +2578,7 @@ int btf__add_datasec_var_info(struct btf *btf, int var_type_id, __u32 offset, __
* - >0, type ID of newly added BTF type; * - >0, type ID of newly added BTF type;
* - <0, on error. * - <0, on error.
*/ */
int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, int btf__add_tag(struct btf *btf, const char *value, int ref_type_id,
int component_idx) int component_idx)
{ {
struct btf_type *t; struct btf_type *t;
@@ -2514,7 +2593,7 @@ int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id,
if (btf_ensure_modifiable(btf)) if (btf_ensure_modifiable(btf))
return libbpf_err(-ENOMEM); return libbpf_err(-ENOMEM);
sz = sizeof(struct btf_type) + sizeof(struct btf_decl_tag); sz = sizeof(struct btf_type) + sizeof(struct btf_tag);
t = btf_add_type_mem(btf, sz); t = btf_add_type_mem(btf, sz);
if (!t) if (!t)
return libbpf_err(-ENOMEM); return libbpf_err(-ENOMEM);
@@ -2524,9 +2603,9 @@ int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id,
return value_off; return value_off;
t->name_off = value_off; t->name_off = value_off;
t->info = btf_type_info(BTF_KIND_DECL_TAG, 0, false); t->info = btf_type_info(BTF_KIND_TAG, 0, false);
t->type = ref_type_id; t->type = ref_type_id;
btf_decl_tag(t)->component_idx = component_idx; btf_tag(t)->component_idx = component_idx;
return btf_commit_type(btf, sz); return btf_commit_type(btf, sz);
} }
@@ -3005,10 +3084,8 @@ int btf__dedup(struct btf *btf, struct btf_ext *btf_ext,
return libbpf_err(-EINVAL); return libbpf_err(-EINVAL);
} }
if (btf_ensure_modifiable(btf)) { if (btf_ensure_modifiable(btf))
err = -ENOMEM; return libbpf_err(-ENOMEM);
goto done;
}
err = btf_dedup_prep(d); err = btf_dedup_prep(d);
if (err) { if (err) {
@@ -3188,7 +3265,7 @@ static struct btf_dedup *btf_dedup_new(struct btf *btf, struct btf_ext *btf_ext,
goto done; goto done;
} }
type_cnt = btf__type_cnt(btf); type_cnt = btf__get_nr_types(btf) + 1;
d->map = malloc(sizeof(__u32) * type_cnt); d->map = malloc(sizeof(__u32) * type_cnt);
if (!d->map) { if (!d->map) {
err = -ENOMEM; err = -ENOMEM;
@@ -3350,7 +3427,7 @@ static bool btf_equal_common(struct btf_type *t1, struct btf_type *t2)
} }
/* Calculate type signature hash of INT or TAG. */ /* Calculate type signature hash of INT or TAG. */
static long btf_hash_int_decl_tag(struct btf_type *t) static long btf_hash_int_tag(struct btf_type *t)
{ {
__u32 info = *(__u32 *)(t + 1); __u32 info = *(__u32 *)(t + 1);
long h; long h;
@@ -3628,8 +3705,8 @@ static int btf_dedup_prep(struct btf_dedup *d)
h = btf_hash_common(t); h = btf_hash_common(t);
break; break;
case BTF_KIND_INT: case BTF_KIND_INT:
case BTF_KIND_DECL_TAG: case BTF_KIND_TAG:
h = btf_hash_int_decl_tag(t); h = btf_hash_int_tag(t);
break; break;
case BTF_KIND_ENUM: case BTF_KIND_ENUM:
h = btf_hash_enum(t); h = btf_hash_enum(t);
@@ -3684,11 +3761,11 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
case BTF_KIND_FUNC_PROTO: case BTF_KIND_FUNC_PROTO:
case BTF_KIND_VAR: case BTF_KIND_VAR:
case BTF_KIND_DATASEC: case BTF_KIND_DATASEC:
case BTF_KIND_DECL_TAG: case BTF_KIND_TAG:
return 0; return 0;
case BTF_KIND_INT: case BTF_KIND_INT:
h = btf_hash_int_decl_tag(t); h = btf_hash_int_tag(t);
for_each_dedup_cand(d, hash_entry, h) { for_each_dedup_cand(d, hash_entry, h) {
cand_id = (__u32)(long)hash_entry->value; cand_id = (__u32)(long)hash_entry->value;
cand = btf_type_by_id(d->btf, cand_id); cand = btf_type_by_id(d->btf, cand_id);
@@ -4305,13 +4382,13 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
} }
break; break;
case BTF_KIND_DECL_TAG: case BTF_KIND_TAG:
ref_type_id = btf_dedup_ref_type(d, t->type); ref_type_id = btf_dedup_ref_type(d, t->type);
if (ref_type_id < 0) if (ref_type_id < 0)
return ref_type_id; return ref_type_id;
t->type = ref_type_id; t->type = ref_type_id;
h = btf_hash_int_decl_tag(t); h = btf_hash_int_tag(t);
for_each_dedup_cand(d, hash_entry, h) { for_each_dedup_cand(d, hash_entry, h) {
cand_id = (__u32)(long)hash_entry->value; cand_id = (__u32)(long)hash_entry->value;
cand = btf_type_by_id(d->btf, cand_id); cand = btf_type_by_id(d->btf, cand_id);
@@ -4594,7 +4671,7 @@ int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ct
case BTF_KIND_TYPEDEF: case BTF_KIND_TYPEDEF:
case BTF_KIND_FUNC: case BTF_KIND_FUNC:
case BTF_KIND_VAR: case BTF_KIND_VAR:
case BTF_KIND_DECL_TAG: case BTF_KIND_TAG:
return visit(&t->type, ctx); return visit(&t->type, ctx);
case BTF_KIND_ARRAY: { case BTF_KIND_ARRAY: {

View File

@@ -123,7 +123,6 @@ LIBBPF_API struct btf *btf__load_from_kernel_by_id_split(__u32 id, struct btf *b
LIBBPF_DEPRECATED_SINCE(0, 6, "use btf__load_from_kernel_by_id instead") LIBBPF_DEPRECATED_SINCE(0, 6, "use btf__load_from_kernel_by_id instead")
LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf); LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf);
LIBBPF_DEPRECATED_SINCE(0, 6, "intended for internal libbpf use only")
LIBBPF_API int btf__finalize_data(struct bpf_object *obj, struct btf *btf); LIBBPF_API int btf__finalize_data(struct bpf_object *obj, struct btf *btf);
LIBBPF_DEPRECATED_SINCE(0, 6, "use btf__load_into_kernel instead") LIBBPF_DEPRECATED_SINCE(0, 6, "use btf__load_into_kernel instead")
LIBBPF_API int btf__load(struct btf *btf); LIBBPF_API int btf__load(struct btf *btf);
@@ -132,9 +131,7 @@ LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
const char *type_name); const char *type_name);
LIBBPF_API __s32 btf__find_by_name_kind(const struct btf *btf, LIBBPF_API __s32 btf__find_by_name_kind(const struct btf *btf,
const char *type_name, __u32 kind); const char *type_name, __u32 kind);
LIBBPF_DEPRECATED_SINCE(0, 7, "use btf__type_cnt() instead; note that btf__get_nr_types() == btf__type_cnt() - 1")
LIBBPF_API __u32 btf__get_nr_types(const struct btf *btf); LIBBPF_API __u32 btf__get_nr_types(const struct btf *btf);
LIBBPF_API __u32 btf__type_cnt(const struct btf *btf);
LIBBPF_API const struct btf *btf__base_btf(const struct btf *btf); LIBBPF_API const struct btf *btf__base_btf(const struct btf *btf);
LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf, LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf,
__u32 id); __u32 id);
@@ -147,9 +144,7 @@ LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
LIBBPF_API int btf__align_of(const struct btf *btf, __u32 id); LIBBPF_API int btf__align_of(const struct btf *btf, __u32 id);
LIBBPF_API int btf__fd(const struct btf *btf); LIBBPF_API int btf__fd(const struct btf *btf);
LIBBPF_API void btf__set_fd(struct btf *btf, int fd); LIBBPF_API void btf__set_fd(struct btf *btf, int fd);
LIBBPF_DEPRECATED_SINCE(0, 7, "use btf__raw_data() instead")
LIBBPF_API const void *btf__get_raw_data(const struct btf *btf, __u32 *size); LIBBPF_API const void *btf__get_raw_data(const struct btf *btf, __u32 *size);
LIBBPF_API const void *btf__raw_data(const struct btf *btf, __u32 *size);
LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset); LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
LIBBPF_API const char *btf__str_by_offset(const struct btf *btf, __u32 offset); LIBBPF_API const char *btf__str_by_offset(const struct btf *btf, __u32 offset);
LIBBPF_API int btf__get_map_kv_tids(const struct btf *btf, const char *map_name, LIBBPF_API int btf__get_map_kv_tids(const struct btf *btf, const char *map_name,
@@ -241,7 +236,7 @@ LIBBPF_API int btf__add_datasec_var_info(struct btf *btf, int var_type_id,
__u32 offset, __u32 byte_sz); __u32 offset, __u32 byte_sz);
/* tag construction API */ /* tag construction API */
LIBBPF_API int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, LIBBPF_API int btf__add_tag(struct btf *btf, const char *value, int ref_type_id,
int component_idx); int component_idx);
struct btf_dedup_opts { struct btf_dedup_opts {
@@ -431,9 +426,9 @@ static inline bool btf_is_float(const struct btf_type *t)
return btf_kind(t) == BTF_KIND_FLOAT; return btf_kind(t) == BTF_KIND_FLOAT;
} }
static inline bool btf_is_decl_tag(const struct btf_type *t) static inline bool btf_is_tag(const struct btf_type *t)
{ {
return btf_kind(t) == BTF_KIND_DECL_TAG; return btf_kind(t) == BTF_KIND_TAG;
} }
static inline __u8 btf_int_encoding(const struct btf_type *t) static inline __u8 btf_int_encoding(const struct btf_type *t)
@@ -504,10 +499,10 @@ btf_var_secinfos(const struct btf_type *t)
return (struct btf_var_secinfo *)(t + 1); return (struct btf_var_secinfo *)(t + 1);
} }
struct btf_decl_tag; struct btf_tag;
static inline struct btf_decl_tag *btf_decl_tag(const struct btf_type *t) static inline struct btf_tag *btf_tag(const struct btf_type *t)
{ {
return (struct btf_decl_tag *)(t + 1); return (struct btf_tag *)(t + 1);
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -188,7 +188,7 @@ err:
static int btf_dump_resize(struct btf_dump *d) static int btf_dump_resize(struct btf_dump *d)
{ {
int err, last_id = btf__type_cnt(d->btf) - 1; int err, last_id = btf__get_nr_types(d->btf);
if (last_id <= d->last_id) if (last_id <= d->last_id)
return 0; return 0;
@@ -262,7 +262,7 @@ int btf_dump__dump_type(struct btf_dump *d, __u32 id)
{ {
int err, i; int err, i;
if (id >= btf__type_cnt(d->btf)) if (id > btf__get_nr_types(d->btf))
return libbpf_err(-EINVAL); return libbpf_err(-EINVAL);
err = btf_dump_resize(d); err = btf_dump_resize(d);
@@ -294,11 +294,11 @@ int btf_dump__dump_type(struct btf_dump *d, __u32 id)
*/ */
static int btf_dump_mark_referenced(struct btf_dump *d) static int btf_dump_mark_referenced(struct btf_dump *d)
{ {
int i, j, n = btf__type_cnt(d->btf); int i, j, n = btf__get_nr_types(d->btf);
const struct btf_type *t; const struct btf_type *t;
__u16 vlen; __u16 vlen;
for (i = d->last_id + 1; i < n; i++) { for (i = d->last_id + 1; i <= n; i++) {
t = btf__type_by_id(d->btf, i); t = btf__type_by_id(d->btf, i);
vlen = btf_vlen(t); vlen = btf_vlen(t);
@@ -316,7 +316,7 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
case BTF_KIND_TYPEDEF: case BTF_KIND_TYPEDEF:
case BTF_KIND_FUNC: case BTF_KIND_FUNC:
case BTF_KIND_VAR: case BTF_KIND_VAR:
case BTF_KIND_DECL_TAG: case BTF_KIND_TAG:
d->type_states[t->type].referenced = 1; d->type_states[t->type].referenced = 1;
break; break;
@@ -584,7 +584,7 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
case BTF_KIND_FUNC: case BTF_KIND_FUNC:
case BTF_KIND_VAR: case BTF_KIND_VAR:
case BTF_KIND_DATASEC: case BTF_KIND_DATASEC:
case BTF_KIND_DECL_TAG: case BTF_KIND_TAG:
d->type_states[id].order_state = ORDERED; d->type_states[id].order_state = ORDERED;
return 0; return 0;
@@ -1562,28 +1562,29 @@ static int btf_dump_get_bitfield_value(struct btf_dump *d,
__u64 *value) __u64 *value)
{ {
__u16 left_shift_bits, right_shift_bits; __u16 left_shift_bits, right_shift_bits;
__u8 nr_copy_bits, nr_copy_bytes;
const __u8 *bytes = data; const __u8 *bytes = data;
__u8 nr_copy_bits; int sz = t->size;
__u64 num = 0; __u64 num = 0;
int i; int i;
/* Maximum supported bitfield size is 64 bits */ /* Maximum supported bitfield size is 64 bits */
if (t->size > 8) { if (sz > 8) {
pr_warn("unexpected bitfield size %d\n", t->size); pr_warn("unexpected bitfield size %d\n", sz);
return -EINVAL; return -EINVAL;
} }
/* Bitfield value retrieval is done in two steps; first relevant bytes are /* Bitfield value retrieval is done in two steps; first relevant bytes are
* stored in num, then we left/right shift num to eliminate irrelevant bits. * stored in num, then we left/right shift num to eliminate irrelevant bits.
*/ */
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
for (i = t->size - 1; i >= 0; i--)
num = num * 256 + bytes[i];
nr_copy_bits = bit_sz + bits_offset; nr_copy_bits = bit_sz + bits_offset;
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ nr_copy_bytes = t->size;
for (i = 0; i < t->size; i++) #if __BYTE_ORDER == __LITTLE_ENDIAN
for (i = nr_copy_bytes - 1; i >= 0; i--)
num = num * 256 + bytes[i];
#elif __BYTE_ORDER == __BIG_ENDIAN
for (i = 0; i < nr_copy_bytes; i++)
num = num * 256 + bytes[i]; num = num * 256 + bytes[i];
nr_copy_bits = t->size * 8 - bits_offset;
#else #else
# error "Unrecognized __BYTE_ORDER__" # error "Unrecognized __BYTE_ORDER__"
#endif #endif
@@ -1657,15 +1658,9 @@ static int btf_dump_base_type_check_zero(struct btf_dump *d,
return 0; return 0;
} }
static bool ptr_is_aligned(const struct btf *btf, __u32 type_id, static bool ptr_is_aligned(const void *data, int data_sz)
const void *data)
{ {
int alignment = btf__align_of(btf, type_id); return ((uintptr_t)data) % data_sz == 0;
if (alignment == 0)
return false;
return ((uintptr_t)data) % alignment == 0;
} }
static int btf_dump_int_data(struct btf_dump *d, static int btf_dump_int_data(struct btf_dump *d,
@@ -1676,10 +1671,9 @@ static int btf_dump_int_data(struct btf_dump *d,
{ {
__u8 encoding = btf_int_encoding(t); __u8 encoding = btf_int_encoding(t);
bool sign = encoding & BTF_INT_SIGNED; bool sign = encoding & BTF_INT_SIGNED;
char buf[16] __attribute__((aligned(16)));
int sz = t->size; int sz = t->size;
if (sz == 0 || sz > sizeof(buf)) { if (sz == 0) {
pr_warn("unexpected size %d for id [%u]\n", sz, type_id); pr_warn("unexpected size %d for id [%u]\n", sz, type_id);
return -EINVAL; return -EINVAL;
} }
@@ -1687,10 +1681,8 @@ static int btf_dump_int_data(struct btf_dump *d,
/* handle packed int data - accesses of integers not aligned on /* handle packed int data - accesses of integers not aligned on
* int boundaries can cause problems on some platforms. * int boundaries can cause problems on some platforms.
*/ */
if (!ptr_is_aligned(d->btf, type_id, data)) { if (!ptr_is_aligned(data, sz))
memcpy(buf, data, sz); return btf_dump_bitfield_data(d, t, data, 0, 0);
data = buf;
}
switch (sz) { switch (sz) {
case 16: { case 16: {
@@ -1700,10 +1692,10 @@ static int btf_dump_int_data(struct btf_dump *d,
/* avoid use of __int128 as some 32-bit platforms do not /* avoid use of __int128 as some 32-bit platforms do not
* support it. * support it.
*/ */
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #if __BYTE_ORDER == __LITTLE_ENDIAN
lsi = ints[0]; lsi = ints[0];
msi = ints[1]; msi = ints[1];
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #elif __BYTE_ORDER == __BIG_ENDIAN
lsi = ints[1]; lsi = ints[1];
msi = ints[0]; msi = ints[0];
#else #else
@@ -1776,7 +1768,7 @@ static int btf_dump_float_data(struct btf_dump *d,
int sz = t->size; int sz = t->size;
/* handle unaligned data; copy to local union */ /* handle unaligned data; copy to local union */
if (!ptr_is_aligned(d->btf, type_id, data)) { if (!ptr_is_aligned(data, sz)) {
memcpy(&fl, data, sz); memcpy(&fl, data, sz);
flp = &fl; flp = &fl;
} }
@@ -1939,7 +1931,7 @@ static int btf_dump_ptr_data(struct btf_dump *d,
__u32 id, __u32 id,
const void *data) const void *data)
{ {
if (ptr_is_aligned(d->btf, id, data) && d->ptr_sz == sizeof(void *)) { if (ptr_is_aligned(data, d->ptr_sz) && d->ptr_sz == sizeof(void *)) {
btf_dump_type_values(d, "%p", *(void **)data); btf_dump_type_values(d, "%p", *(void **)data);
} else { } else {
union ptr_data pt; union ptr_data pt;
@@ -1959,8 +1951,10 @@ static int btf_dump_get_enum_value(struct btf_dump *d,
__u32 id, __u32 id,
__s64 *value) __s64 *value)
{ {
int sz = t->size;
/* handle unaligned enum value */ /* handle unaligned enum value */
if (!ptr_is_aligned(d->btf, id, data)) { if (!ptr_is_aligned(data, sz)) {
__u64 val; __u64 val;
int err; int err;
@@ -2223,7 +2217,7 @@ static int btf_dump_dump_type_data(struct btf_dump *d,
case BTF_KIND_FWD: case BTF_KIND_FWD:
case BTF_KIND_FUNC: case BTF_KIND_FUNC:
case BTF_KIND_FUNC_PROTO: case BTF_KIND_FUNC_PROTO:
case BTF_KIND_DECL_TAG: case BTF_KIND_TAG:
err = btf_dump_unsupported_data(d, t, id); err = btf_dump_unsupported_data(d, t, id);
break; break;
case BTF_KIND_INT: case BTF_KIND_INT:

View File

@@ -13,7 +13,6 @@
#include "hashmap.h" #include "hashmap.h"
#include "bpf_gen_internal.h" #include "bpf_gen_internal.h"
#include "skel_internal.h" #include "skel_internal.h"
#include <asm/byteorder.h>
#define MAX_USED_MAPS 64 #define MAX_USED_MAPS 64
#define MAX_USED_PROGS 32 #define MAX_USED_PROGS 32
@@ -432,7 +431,7 @@ void bpf_gen__load_btf(struct bpf_gen *gen, const void *btf_raw_data,
} }
void bpf_gen__map_create(struct bpf_gen *gen, void bpf_gen__map_create(struct bpf_gen *gen,
struct bpf_create_map_params *map_attr, int map_idx) struct bpf_create_map_attr *map_attr, int map_idx)
{ {
int attr_size = offsetofend(union bpf_attr, btf_vmlinux_value_type_id); int attr_size = offsetofend(union bpf_attr, btf_vmlinux_value_type_id);
bool close_inner_map_fd = false; bool close_inner_map_fd = false;
@@ -444,7 +443,6 @@ void bpf_gen__map_create(struct bpf_gen *gen,
attr.key_size = map_attr->key_size; attr.key_size = map_attr->key_size;
attr.value_size = map_attr->value_size; attr.value_size = map_attr->value_size;
attr.map_flags = map_attr->map_flags; attr.map_flags = map_attr->map_flags;
attr.map_extra = map_attr->map_extra;
memcpy(attr.map_name, map_attr->name, memcpy(attr.map_name, map_attr->name,
min((unsigned)strlen(map_attr->name), BPF_OBJ_NAME_LEN - 1)); min((unsigned)strlen(map_attr->name), BPF_OBJ_NAME_LEN - 1));
attr.numa_node = map_attr->numa_node; attr.numa_node = map_attr->numa_node;
@@ -561,7 +559,7 @@ static void emit_find_attach_target(struct bpf_gen *gen)
} }
void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, bool is_weak, void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, bool is_weak,
bool is_typeless, int kind, int insn_idx) int kind, int insn_idx)
{ {
struct ksym_relo_desc *relo; struct ksym_relo_desc *relo;
@@ -574,7 +572,6 @@ void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, bool is_weak,
relo += gen->relo_cnt; relo += gen->relo_cnt;
relo->name = name; relo->name = name;
relo->is_weak = is_weak; relo->is_weak = is_weak;
relo->is_typeless = is_typeless;
relo->kind = kind; relo->kind = kind;
relo->insn_idx = insn_idx; relo->insn_idx = insn_idx;
gen->relo_cnt++; gen->relo_cnt++;
@@ -584,9 +581,8 @@ void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, bool is_weak,
static struct ksym_desc *get_ksym_desc(struct bpf_gen *gen, struct ksym_relo_desc *relo) static struct ksym_desc *get_ksym_desc(struct bpf_gen *gen, struct ksym_relo_desc *relo)
{ {
struct ksym_desc *kdesc; struct ksym_desc *kdesc;
int i;
for (i = 0; i < gen->nr_ksyms; i++) { for (int i = 0; i < gen->nr_ksyms; i++) {
if (!strcmp(gen->ksyms[i].name, relo->name)) { if (!strcmp(gen->ksyms[i].name, relo->name)) {
gen->ksyms[i].ref++; gen->ksyms[i].ref++;
return &gen->ksyms[i]; return &gen->ksyms[i];
@@ -625,29 +621,6 @@ static void emit_bpf_find_by_name_kind(struct bpf_gen *gen, struct ksym_relo_des
debug_ret(gen, "find_by_name_kind(%s,%d)", relo->name, relo->kind); debug_ret(gen, "find_by_name_kind(%s,%d)", relo->name, relo->kind);
} }
/* Overwrites BPF_REG_{0, 1, 2, 3, 4, 7}
* Returns result in BPF_REG_7
* Returns u64 symbol addr in BPF_REG_9
*/
static void emit_bpf_kallsyms_lookup_name(struct bpf_gen *gen, struct ksym_relo_desc *relo)
{
int name_off, len = strlen(relo->name) + 1, res_off;
name_off = add_data(gen, relo->name, len);
res_off = add_data(gen, NULL, 8); /* res is u64 */
emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
0, 0, 0, name_off));
emit(gen, BPF_MOV64_IMM(BPF_REG_2, len));
emit(gen, BPF_MOV64_IMM(BPF_REG_3, 0));
emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_4, BPF_PSEUDO_MAP_IDX_VALUE,
0, 0, 0, res_off));
emit(gen, BPF_MOV64_REG(BPF_REG_7, BPF_REG_4));
emit(gen, BPF_EMIT_CALL(BPF_FUNC_kallsyms_lookup_name));
emit(gen, BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0));
emit(gen, BPF_MOV64_REG(BPF_REG_7, BPF_REG_0));
debug_ret(gen, "kallsyms_lookup_name(%s,%d)", relo->name, relo->kind);
}
/* Expects: /* Expects:
* BPF_REG_8 - pointer to instruction * BPF_REG_8 - pointer to instruction
* *
@@ -727,27 +700,10 @@ log:
relo->name, kdesc->ref); relo->name, kdesc->ref);
} }
static void emit_ksym_relo_log(struct bpf_gen *gen, struct ksym_relo_desc *relo,
int ref)
{
if (!gen->log_level)
return;
emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_8,
offsetof(struct bpf_insn, imm)));
emit(gen, BPF_LDX_MEM(BPF_H, BPF_REG_9, BPF_REG_8, sizeof(struct bpf_insn) +
offsetof(struct bpf_insn, imm)));
debug_regs(gen, BPF_REG_7, BPF_REG_9, " var t=%d w=%d (%s:count=%d): imm[0]: %%d, imm[1]: %%d",
relo->is_typeless, relo->is_weak, relo->name, ref);
emit(gen, BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_8, offsetofend(struct bpf_insn, code)));
debug_regs(gen, BPF_REG_9, -1, " var t=%d w=%d (%s:count=%d): insn.reg",
relo->is_typeless, relo->is_weak, relo->name, ref);
}
/* Expects: /* Expects:
* BPF_REG_8 - pointer to instruction * BPF_REG_8 - pointer to instruction
*/ */
static void emit_relo_ksym_typeless(struct bpf_gen *gen, static void emit_relo_ksym_btf(struct bpf_gen *gen, struct ksym_relo_desc *relo, int insn)
struct ksym_relo_desc *relo, int insn)
{ {
struct ksym_desc *kdesc; struct ksym_desc *kdesc;
@@ -762,81 +718,25 @@ static void emit_relo_ksym_typeless(struct bpf_gen *gen,
kdesc->insn + sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm)); kdesc->insn + sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm));
goto log; goto log;
} }
/* remember insn offset, so we can copy ksym addr later */
kdesc->insn = insn;
/* skip typeless ksym_desc in fd closing loop in cleanup_relos */
kdesc->typeless = true;
emit_bpf_kallsyms_lookup_name(gen, relo);
emit(gen, BPF_JMP_IMM(BPF_JEQ, BPF_REG_7, -ENOENT, 1));
emit_check_err(gen);
/* store lower half of addr into insn[insn_idx].imm */
emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_8, BPF_REG_9, offsetof(struct bpf_insn, imm)));
/* store upper half of addr into insn[insn_idx + 1].imm */
emit(gen, BPF_ALU64_IMM(BPF_RSH, BPF_REG_9, 32));
emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_8, BPF_REG_9,
sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm)));
log:
emit_ksym_relo_log(gen, relo, kdesc->ref);
}
static __u32 src_reg_mask(void)
{
#if defined(__LITTLE_ENDIAN_BITFIELD)
return 0x0f; /* src_reg,dst_reg,... */
#elif defined(__BIG_ENDIAN_BITFIELD)
return 0xf0; /* dst_reg,src_reg,... */
#else
#error "Unsupported bit endianness, cannot proceed"
#endif
}
/* Expects:
* BPF_REG_8 - pointer to instruction
*/
static void emit_relo_ksym_btf(struct bpf_gen *gen, struct ksym_relo_desc *relo, int insn)
{
struct ksym_desc *kdesc;
__u32 reg_mask;
kdesc = get_ksym_desc(gen, relo);
if (!kdesc)
return;
/* try to copy from existing ldimm64 insn */
if (kdesc->ref > 1) {
move_blob2blob(gen, insn + offsetof(struct bpf_insn, imm), 4,
kdesc->insn + offsetof(struct bpf_insn, imm));
move_blob2blob(gen, insn + sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm), 4,
kdesc->insn + sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm));
emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_8, offsetof(struct bpf_insn, imm)));
/* jump over src_reg adjustment if imm is not 0 */
emit(gen, BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 0, 3));
goto clear_src_reg;
}
/* remember insn offset, so we can copy BTF ID and FD later */ /* remember insn offset, so we can copy BTF ID and FD later */
kdesc->insn = insn; kdesc->insn = insn;
emit_bpf_find_by_name_kind(gen, relo); emit_bpf_find_by_name_kind(gen, relo);
if (!relo->is_weak) emit_check_err(gen);
emit_check_err(gen);
/* set default values as 0 */
emit(gen, BPF_ST_MEM(BPF_W, BPF_REG_8, offsetof(struct bpf_insn, imm), 0));
emit(gen, BPF_ST_MEM(BPF_W, BPF_REG_8, sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm), 0));
/* skip success case stores if ret < 0 */
emit(gen, BPF_JMP_IMM(BPF_JSLT, BPF_REG_7, 0, 4));
/* store btf_id into insn[insn_idx].imm */ /* store btf_id into insn[insn_idx].imm */
emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_8, BPF_REG_7, offsetof(struct bpf_insn, imm))); emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_8, BPF_REG_7, offsetof(struct bpf_insn, imm)));
/* store btf_obj_fd into insn[insn_idx + 1].imm */ /* store btf_obj_fd into insn[insn_idx + 1].imm */
emit(gen, BPF_ALU64_IMM(BPF_RSH, BPF_REG_7, 32)); emit(gen, BPF_ALU64_IMM(BPF_RSH, BPF_REG_7, 32));
emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_8, BPF_REG_7, emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_8, BPF_REG_7,
sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm))); sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm)));
emit(gen, BPF_JMP_IMM(BPF_JSGE, BPF_REG_7, 0, 3)); log:
clear_src_reg: if (!gen->log_level)
/* clear bpf_object__relocate_data's src_reg assignment, otherwise we get a verifier failure */ return;
reg_mask = src_reg_mask(); emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_8,
emit(gen, BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_8, offsetofend(struct bpf_insn, code))); offsetof(struct bpf_insn, imm)));
emit(gen, BPF_ALU32_IMM(BPF_AND, BPF_REG_9, reg_mask)); emit(gen, BPF_LDX_MEM(BPF_H, BPF_REG_9, BPF_REG_8, sizeof(struct bpf_insn) +
emit(gen, BPF_STX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, offsetofend(struct bpf_insn, code))); offsetof(struct bpf_insn, imm)));
debug_regs(gen, BPF_REG_7, BPF_REG_9, " var (%s:count=%d): imm: %%d, fd: %%d",
emit_ksym_relo_log(gen, relo, kdesc->ref); relo->name, kdesc->ref);
} }
static void emit_relo(struct bpf_gen *gen, struct ksym_relo_desc *relo, int insns) static void emit_relo(struct bpf_gen *gen, struct ksym_relo_desc *relo, int insns)
@@ -848,10 +748,7 @@ static void emit_relo(struct bpf_gen *gen, struct ksym_relo_desc *relo, int insn
emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_8, BPF_PSEUDO_MAP_IDX_VALUE, 0, 0, 0, insn)); emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_8, BPF_PSEUDO_MAP_IDX_VALUE, 0, 0, 0, insn));
switch (relo->kind) { switch (relo->kind) {
case BTF_KIND_VAR: case BTF_KIND_VAR:
if (relo->is_typeless) emit_relo_ksym_btf(gen, relo, insn);
emit_relo_ksym_typeless(gen, relo, insn);
else
emit_relo_ksym_btf(gen, relo, insn);
break; break;
case BTF_KIND_FUNC: case BTF_KIND_FUNC:
emit_relo_kfunc_btf(gen, relo, insn); emit_relo_kfunc_btf(gen, relo, insn);
@@ -876,13 +773,12 @@ static void cleanup_relos(struct bpf_gen *gen, int insns)
int i, insn; int i, insn;
for (i = 0; i < gen->nr_ksyms; i++) { for (i = 0; i < gen->nr_ksyms; i++) {
/* only close fds for typed ksyms and kfuncs */ if (gen->ksyms[i].kind == BTF_KIND_VAR) {
if (gen->ksyms[i].kind == BTF_KIND_VAR && !gen->ksyms[i].typeless) {
/* close fd recorded in insn[insn_idx + 1].imm */ /* close fd recorded in insn[insn_idx + 1].imm */
insn = gen->ksyms[i].insn; insn = gen->ksyms[i].insn;
insn += sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm); insn += sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm);
emit_sys_close_blob(gen, insn); emit_sys_close_blob(gen, insn);
} else if (gen->ksyms[i].kind == BTF_KIND_FUNC) { } else { /* BTF_KIND_FUNC */
emit_sys_close_blob(gen, blob_fd_array_off(gen, gen->ksyms[i].off)); emit_sys_close_blob(gen, blob_fd_array_off(gen, gen->ksyms[i].off));
if (gen->ksyms[i].off < MAX_FD_ARRAY_SZ) if (gen->ksyms[i].off < MAX_FD_ARRAY_SZ)
gen->nr_fd_array--; gen->nr_fd_array--;

File diff suppressed because it is too large Load Diff

View File

@@ -168,8 +168,7 @@ LIBBPF_API struct bpf_program *
bpf_object__find_program_by_name(const struct bpf_object *obj, bpf_object__find_program_by_name(const struct bpf_object *obj,
const char *name); const char *name);
LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "track bpf_objects in application code instead") LIBBPF_API struct bpf_object *bpf_object__next(struct bpf_object *prev);
struct bpf_object *bpf_object__next(struct bpf_object *prev);
#define bpf_object__for_each_safe(pos, tmp) \ #define bpf_object__for_each_safe(pos, tmp) \
for ((pos) = bpf_object__next(NULL), \ for ((pos) = bpf_object__next(NULL), \
(tmp) = bpf_object__next(pos); \ (tmp) = bpf_object__next(pos); \
@@ -225,51 +224,14 @@ LIBBPF_API bool bpf_program__autoload(const struct bpf_program *prog);
LIBBPF_API int bpf_program__set_autoload(struct bpf_program *prog, bool autoload); LIBBPF_API int bpf_program__set_autoload(struct bpf_program *prog, bool autoload);
/* returns program size in bytes */ /* returns program size in bytes */
LIBBPF_DEPRECATED_SINCE(0, 7, "use bpf_program__insn_cnt() instead")
LIBBPF_API size_t bpf_program__size(const struct bpf_program *prog); LIBBPF_API size_t bpf_program__size(const struct bpf_program *prog);
struct bpf_insn; LIBBPF_API int bpf_program__load(struct bpf_program *prog, char *license,
__u32 kern_version);
/**
* @brief **bpf_program__insns()** gives read-only access to BPF program's
* underlying BPF instructions.
* @param prog BPF program for which to return instructions
* @return a pointer to an array of BPF instructions that belong to the
* specified BPF program
*
* Returned pointer is always valid and not NULL. Number of `struct bpf_insn`
* pointed to can be fetched using **bpf_program__insn_cnt()** API.
*
* Keep in mind, libbpf can modify and append/delete BPF program's
* instructions as it processes BPF object file and prepares everything for
* uploading into the kernel. So depending on the point in BPF object
* lifetime, **bpf_program__insns()** can return different sets of
* instructions. As an example, during BPF object load phase BPF program
* instructions will be CO-RE-relocated, BPF subprograms instructions will be
* appended, ldimm64 instructions will have FDs embedded, etc. So instructions
* returned before **bpf_object__load()** and after it might be quite
* different.
*/
LIBBPF_API const struct bpf_insn *bpf_program__insns(const struct bpf_program *prog);
/**
* @brief **bpf_program__insn_cnt()** returns number of `struct bpf_insn`'s
* that form specified BPF program.
* @param prog BPF program for which to return number of BPF instructions
*
* See **bpf_program__insns()** documentation for notes on how libbpf can
* change instructions and their count during different phases of
* **bpf_object** lifetime.
*/
LIBBPF_API size_t bpf_program__insn_cnt(const struct bpf_program *prog);
LIBBPF_DEPRECATED_SINCE(0, 6, "use bpf_object__load() instead")
LIBBPF_API int bpf_program__load(struct bpf_program *prog, const char *license, __u32 kern_version);
LIBBPF_API int bpf_program__fd(const struct bpf_program *prog); LIBBPF_API int bpf_program__fd(const struct bpf_program *prog);
LIBBPF_DEPRECATED_SINCE(0, 7, "multi-instance bpf_program support is deprecated")
LIBBPF_API int bpf_program__pin_instance(struct bpf_program *prog, LIBBPF_API int bpf_program__pin_instance(struct bpf_program *prog,
const char *path, const char *path,
int instance); int instance);
LIBBPF_DEPRECATED_SINCE(0, 7, "multi-instance bpf_program support is deprecated")
LIBBPF_API int bpf_program__unpin_instance(struct bpf_program *prog, LIBBPF_API int bpf_program__unpin_instance(struct bpf_program *prog,
const char *path, const char *path,
int instance); int instance);
@@ -403,6 +365,8 @@ LIBBPF_API struct bpf_link *
bpf_program__attach_iter(const struct bpf_program *prog, bpf_program__attach_iter(const struct bpf_program *prog,
const struct bpf_iter_attach_opts *opts); const struct bpf_iter_attach_opts *opts);
struct bpf_insn;
/* /*
* Libbpf allows callers to adjust BPF programs before being loaded * Libbpf allows callers to adjust BPF programs before being loaded
* into kernel. One program in an object file can be transformed into * into kernel. One program in an object file can be transformed into
@@ -431,7 +395,7 @@ bpf_program__attach_iter(const struct bpf_program *prog,
* one instance. In this case bpf_program__fd(prog) is equal to * one instance. In this case bpf_program__fd(prog) is equal to
* bpf_program__nth_fd(prog, 0). * bpf_program__nth_fd(prog, 0).
*/ */
LIBBPF_DEPRECATED_SINCE(0, 7, "use bpf_program__insns() for getting bpf_program instructions")
struct bpf_prog_prep_result { struct bpf_prog_prep_result {
/* /*
* If not NULL, load new instruction array. * If not NULL, load new instruction array.
@@ -460,11 +424,9 @@ typedef int (*bpf_program_prep_t)(struct bpf_program *prog, int n,
struct bpf_insn *insns, int insns_cnt, struct bpf_insn *insns, int insns_cnt,
struct bpf_prog_prep_result *res); struct bpf_prog_prep_result *res);
LIBBPF_DEPRECATED_SINCE(0, 7, "use bpf_program__insns() for getting bpf_program instructions")
LIBBPF_API int bpf_program__set_prep(struct bpf_program *prog, int nr_instance, LIBBPF_API int bpf_program__set_prep(struct bpf_program *prog, int nr_instance,
bpf_program_prep_t prep); bpf_program_prep_t prep);
LIBBPF_DEPRECATED_SINCE(0, 7, "multi-instance bpf_program support is deprecated")
LIBBPF_API int bpf_program__nth_fd(const struct bpf_program *prog, int n); LIBBPF_API int bpf_program__nth_fd(const struct bpf_program *prog, int n);
/* /*
@@ -600,9 +562,6 @@ LIBBPF_API __u32 bpf_map__btf_value_type_id(const struct bpf_map *map);
/* get/set map if_index */ /* get/set map if_index */
LIBBPF_API __u32 bpf_map__ifindex(const struct bpf_map *map); LIBBPF_API __u32 bpf_map__ifindex(const struct bpf_map *map);
LIBBPF_API int bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex); LIBBPF_API int bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex);
/* get/set map map_extra flags */
LIBBPF_API __u64 bpf_map__map_extra(const struct bpf_map *map);
LIBBPF_API int bpf_map__set_map_extra(struct bpf_map *map, __u64 map_extra);
typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *); typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
LIBBPF_API int bpf_map__set_priv(struct bpf_map *map, void *priv, LIBBPF_API int bpf_map__set_priv(struct bpf_map *map, void *priv,
@@ -918,15 +877,12 @@ struct bpf_prog_info_linear {
__u8 data[]; __u8 data[];
}; };
LIBBPF_DEPRECATED_SINCE(0, 6, "use a custom linear prog_info wrapper")
LIBBPF_API struct bpf_prog_info_linear * LIBBPF_API struct bpf_prog_info_linear *
bpf_program__get_prog_info_linear(int fd, __u64 arrays); bpf_program__get_prog_info_linear(int fd, __u64 arrays);
LIBBPF_DEPRECATED_SINCE(0, 6, "use a custom linear prog_info wrapper")
LIBBPF_API void LIBBPF_API void
bpf_program__bpil_addr_to_offs(struct bpf_prog_info_linear *info_linear); bpf_program__bpil_addr_to_offs(struct bpf_prog_info_linear *info_linear);
LIBBPF_DEPRECATED_SINCE(0, 6, "use a custom linear prog_info wrapper")
LIBBPF_API void LIBBPF_API void
bpf_program__bpil_offs_to_addr(struct bpf_prog_info_linear *info_linear); bpf_program__bpil_offs_to_addr(struct bpf_prog_info_linear *info_linear);

View File

@@ -389,16 +389,10 @@ LIBBPF_0.5.0 {
LIBBPF_0.6.0 { LIBBPF_0.6.0 {
global: global:
bpf_map__map_extra;
bpf_map__set_map_extra;
bpf_object__next_map; bpf_object__next_map;
bpf_object__next_program; bpf_object__next_program;
bpf_object__prev_map; bpf_object__prev_map;
bpf_object__prev_program; bpf_object__prev_program;
bpf_program__insn_cnt;
bpf_program__insns;
btf__add_btf; btf__add_btf;
btf__add_decl_tag; btf__add_tag;
btf__raw_data;
btf__type_cnt;
} LIBBPF_0.5.0; } LIBBPF_0.5.0;

View File

@@ -13,8 +13,6 @@
#include <limits.h> #include <limits.h>
#include <errno.h> #include <errno.h>
#include <linux/err.h> #include <linux/err.h>
#include <fcntl.h>
#include <unistd.h>
#include "libbpf_legacy.h" #include "libbpf_legacy.h"
#include "relo_core.h" #include "relo_core.h"
@@ -54,8 +52,8 @@
#endif #endif
/* Older libelf all end up in this expression, for both 32 and 64 bit */ /* Older libelf all end up in this expression, for both 32 and 64 bit */
#ifndef ELF64_ST_VISIBILITY #ifndef GELF_ST_VISIBILITY
#define ELF64_ST_VISIBILITY(o) ((o) & 0x03) #define GELF_ST_VISIBILITY(o) ((o) & 0x03)
#endif #endif
#define BTF_INFO_ENC(kind, kind_flag, vlen) \ #define BTF_INFO_ENC(kind, kind_flag, vlen) \
@@ -71,8 +69,8 @@
#define BTF_VAR_SECINFO_ENC(type, offset, size) (type), (offset), (size) #define BTF_VAR_SECINFO_ENC(type, offset, size) (type), (offset), (size)
#define BTF_TYPE_FLOAT_ENC(name, sz) \ #define BTF_TYPE_FLOAT_ENC(name, sz) \
BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 0), sz) BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 0), sz)
#define BTF_TYPE_DECL_TAG_ENC(value, type, component_idx) \ #define BTF_TYPE_TAG_ENC(value, type, component_idx) \
BTF_TYPE_ENC(value, BTF_INFO_ENC(BTF_KIND_DECL_TAG, 0, 0), type), (component_idx) BTF_TYPE_ENC(value, BTF_INFO_ENC(BTF_KIND_TAG, 0, 0), type), (component_idx)
#ifndef likely #ifndef likely
#define likely(x) __builtin_expect(!!(x), 1) #define likely(x) __builtin_expect(!!(x), 1)
@@ -195,9 +193,8 @@ enum map_def_parts {
MAP_DEF_NUMA_NODE = 0x080, MAP_DEF_NUMA_NODE = 0x080,
MAP_DEF_PINNING = 0x100, MAP_DEF_PINNING = 0x100,
MAP_DEF_INNER_MAP = 0x200, MAP_DEF_INNER_MAP = 0x200,
MAP_DEF_MAP_EXTRA = 0x400,
MAP_DEF_ALL = 0x7ff, /* combination of all above */ MAP_DEF_ALL = 0x3ff, /* combination of all above */
}; };
struct btf_map_def { struct btf_map_def {
@@ -211,7 +208,6 @@ struct btf_map_def {
__u32 map_flags; __u32 map_flags;
__u32 numa_node; __u32 numa_node;
__u32 pinning; __u32 pinning;
__u64 map_extra;
}; };
int parse_btf_map_def(const char *map_name, struct btf *btf, int parse_btf_map_def(const char *map_name, struct btf *btf,
@@ -307,27 +303,10 @@ struct bpf_prog_load_params {
int libbpf__bpf_prog_load(const struct bpf_prog_load_params *load_attr); int libbpf__bpf_prog_load(const struct bpf_prog_load_params *load_attr);
struct bpf_create_map_params { int bpf_object__section_size(const struct bpf_object *obj, const char *name,
const char *name; __u32 *size);
enum bpf_map_type map_type; int bpf_object__variable_offset(const struct bpf_object *obj, const char *name,
__u32 map_flags; __u32 *off);
__u32 key_size;
__u32 value_size;
__u32 max_entries;
__u32 numa_node;
__u32 btf_fd;
__u32 btf_key_type_id;
__u32 btf_value_type_id;
__u32 map_ifindex;
union {
__u32 inner_map_fd;
__u32 btf_vmlinux_value_type_id;
};
__u64 map_extra;
};
int libbpf__bpf_create_map_xattr(const struct bpf_create_map_params *create_attr);
struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf); struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf);
void btf_get_kernel_prefix_kind(enum bpf_attach_type attach_type, void btf_get_kernel_prefix_kind(enum bpf_attach_type attach_type,
const char **prefix, int *kind); const char **prefix, int *kind);
@@ -493,26 +472,4 @@ static inline bool is_ldimm64_insn(struct bpf_insn *insn)
return insn->code == (BPF_LD | BPF_IMM | BPF_DW); return insn->code == (BPF_LD | BPF_IMM | BPF_DW);
} }
/* if fd is stdin, stdout, or stderr, dup to a fd greater than 2
* Takes ownership of the fd passed in, and closes it if calling
* fcntl(fd, F_DUPFD_CLOEXEC, 3).
*/
static inline int ensure_good_fd(int fd)
{
int old_fd = fd, saved_errno;
if (fd < 0)
return fd;
if (fd < 3) {
fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
saved_errno = errno;
close(old_fd);
if (fd < 0) {
pr_warn("failed to dup FD %d to FD > 2: %d\n", old_fd, -saved_errno);
errno = saved_errno;
}
}
return fd;
}
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */ #endif /* __LIBBPF_LIBBPF_INTERNAL_H */

View File

@@ -52,17 +52,8 @@ enum libbpf_strict_mode {
* allowed, with LIBBPF_STRICT_SEC_PREFIX this will become * allowed, with LIBBPF_STRICT_SEC_PREFIX this will become
* unrecognized by libbpf and would have to be just SEC("xdp") and * unrecognized by libbpf and would have to be just SEC("xdp") and
* SEC("xdp") and SEC("perf_event"). * SEC("xdp") and SEC("perf_event").
*
* Note, in this mode the program pin path will be based on the
* function name instead of section name.
*/ */
LIBBPF_STRICT_SEC_NAME = 0x04, LIBBPF_STRICT_SEC_NAME = 0x04,
/*
* Disable the global 'bpf_objects_list'. Maintaining this list adds
* a race condition to bpf_object__open() and bpf_object__close().
* Clients can maintain it on their own if it is valuable for them.
*/
LIBBPF_STRICT_NO_OBJECT_LIST = 0x08,
__LIBBPF_STRICT_LAST, __LIBBPF_STRICT_LAST,
}; };

View File

@@ -33,7 +33,7 @@ static int get_vendor_id(int ifindex)
snprintf(path, sizeof(path), "/sys/class/net/%s/device/vendor", ifname); snprintf(path, sizeof(path), "/sys/class/net/%s/device/vendor", ifname);
fd = open(path, O_RDONLY | O_CLOEXEC); fd = open(path, O_RDONLY);
if (fd < 0) if (fd < 0)
return -1; return -1;

View File

@@ -15,6 +15,7 @@
#include <linux/btf.h> #include <linux/btf.h>
#include <elf.h> #include <elf.h>
#include <libelf.h> #include <libelf.h>
#include <gelf.h>
#include <fcntl.h> #include <fcntl.h>
#include "libbpf.h" #include "libbpf.h"
#include "btf.h" #include "btf.h"
@@ -301,7 +302,7 @@ static int init_output_elf(struct bpf_linker *linker, const char *file)
if (!linker->filename) if (!linker->filename)
return -ENOMEM; return -ENOMEM;
linker->fd = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644); linker->fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (linker->fd < 0) { if (linker->fd < 0) {
err = -errno; err = -errno;
pr_warn("failed to create '%s': %d\n", file, err); pr_warn("failed to create '%s': %d\n", file, err);
@@ -323,12 +324,12 @@ static int init_output_elf(struct bpf_linker *linker, const char *file)
linker->elf_hdr->e_machine = EM_BPF; linker->elf_hdr->e_machine = EM_BPF;
linker->elf_hdr->e_type = ET_REL; linker->elf_hdr->e_type = ET_REL;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #if __BYTE_ORDER == __LITTLE_ENDIAN
linker->elf_hdr->e_ident[EI_DATA] = ELFDATA2LSB; linker->elf_hdr->e_ident[EI_DATA] = ELFDATA2LSB;
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #elif __BYTE_ORDER == __BIG_ENDIAN
linker->elf_hdr->e_ident[EI_DATA] = ELFDATA2MSB; linker->elf_hdr->e_ident[EI_DATA] = ELFDATA2MSB;
#else #else
#error "Unknown __BYTE_ORDER__" #error "Unknown __BYTE_ORDER"
#endif #endif
/* STRTAB */ /* STRTAB */
@@ -538,12 +539,12 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
const struct bpf_linker_file_opts *opts, const struct bpf_linker_file_opts *opts,
struct src_obj *obj) struct src_obj *obj)
{ {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #if __BYTE_ORDER == __LITTLE_ENDIAN
const int host_endianness = ELFDATA2LSB; const int host_endianness = ELFDATA2LSB;
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #elif __BYTE_ORDER == __BIG_ENDIAN
const int host_endianness = ELFDATA2MSB; const int host_endianness = ELFDATA2MSB;
#else #else
#error "Unknown __BYTE_ORDER__" #error "Unknown __BYTE_ORDER"
#endif #endif
int err = 0; int err = 0;
Elf_Scn *scn; Elf_Scn *scn;
@@ -556,7 +557,7 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
obj->filename = filename; obj->filename = filename;
obj->fd = open(filename, O_RDONLY | O_CLOEXEC); obj->fd = open(filename, O_RDONLY);
if (obj->fd < 0) { if (obj->fd < 0) {
err = -errno; err = -errno;
pr_warn("failed to open file '%s': %d\n", filename, err); pr_warn("failed to open file '%s': %d\n", filename, err);
@@ -920,7 +921,7 @@ static int check_btf_type_id(__u32 *type_id, void *ctx)
{ {
struct btf *btf = ctx; struct btf *btf = ctx;
if (*type_id >= btf__type_cnt(btf)) if (*type_id > btf__get_nr_types(btf))
return -EINVAL; return -EINVAL;
return 0; return 0;
@@ -947,8 +948,8 @@ static int linker_sanity_check_btf(struct src_obj *obj)
if (!obj->btf) if (!obj->btf)
return 0; return 0;
n = btf__type_cnt(obj->btf); n = btf__get_nr_types(obj->btf);
for (i = 1; i < n; i++) { for (i = 1; i <= n; i++) {
t = btf_type_by_id(obj->btf, i); t = btf_type_by_id(obj->btf, i);
err = err ?: btf_type_visit_type_ids(t, check_btf_type_id, obj->btf); err = err ?: btf_type_visit_type_ids(t, check_btf_type_id, obj->btf);
@@ -1658,8 +1659,8 @@ static int find_glob_sym_btf(struct src_obj *obj, Elf64_Sym *sym, const char *sy
return -EINVAL; return -EINVAL;
} }
n = btf__type_cnt(obj->btf); n = btf__get_nr_types(obj->btf);
for (i = 1; i < n; i++) { for (i = 1; i <= n; i++) {
t = btf__type_by_id(obj->btf, i); t = btf__type_by_id(obj->btf, i);
/* some global and extern FUNCs and VARs might not be associated with any /* some global and extern FUNCs and VARs might not be associated with any
@@ -2130,8 +2131,8 @@ static int linker_fixup_btf(struct src_obj *obj)
if (!obj->btf) if (!obj->btf)
return 0; return 0;
n = btf__type_cnt(obj->btf); n = btf__get_nr_types(obj->btf);
for (i = 1; i < n; i++) { for (i = 1; i <= n; i++) {
struct btf_var_secinfo *vi; struct btf_var_secinfo *vi;
struct btf_type *t; struct btf_type *t;
@@ -2234,14 +2235,14 @@ static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj)
if (!obj->btf) if (!obj->btf)
return 0; return 0;
start_id = btf__type_cnt(linker->btf); start_id = btf__get_nr_types(linker->btf) + 1;
n = btf__type_cnt(obj->btf); n = btf__get_nr_types(obj->btf);
obj->btf_type_map = calloc(n + 1, sizeof(int)); obj->btf_type_map = calloc(n + 1, sizeof(int));
if (!obj->btf_type_map) if (!obj->btf_type_map)
return -ENOMEM; return -ENOMEM;
for (i = 1; i < n; i++) { for (i = 1; i <= n; i++) {
struct glob_sym *glob_sym = NULL; struct glob_sym *glob_sym = NULL;
t = btf__type_by_id(obj->btf, i); t = btf__type_by_id(obj->btf, i);
@@ -2296,8 +2297,8 @@ static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj)
} }
/* remap all the types except DATASECs */ /* remap all the types except DATASECs */
n = btf__type_cnt(linker->btf); n = btf__get_nr_types(linker->btf);
for (i = start_id; i < n; i++) { for (i = start_id; i <= n; i++) {
struct btf_type *dst_t = btf_type_by_id(linker->btf, i); struct btf_type *dst_t = btf_type_by_id(linker->btf, i);
if (btf_type_visit_type_ids(dst_t, remap_type_id, obj->btf_type_map)) if (btf_type_visit_type_ids(dst_t, remap_type_id, obj->btf_type_map))
@@ -2656,7 +2657,7 @@ static int finalize_btf(struct bpf_linker *linker)
__u32 raw_sz; __u32 raw_sz;
/* bail out if no BTF data was produced */ /* bail out if no BTF data was produced */
if (btf__type_cnt(linker->btf) == 1) if (btf__get_nr_types(linker->btf) == 0)
return 0; return 0;
for (i = 1; i < linker->sec_cnt; i++) { for (i = 1; i < linker->sec_cnt; i++) {
@@ -2693,7 +2694,7 @@ static int finalize_btf(struct bpf_linker *linker)
} }
/* Emit .BTF section */ /* Emit .BTF section */
raw_data = btf__raw_data(linker->btf, &raw_sz); raw_data = btf__get_raw_data(linker->btf, &raw_sz);
if (!raw_data) if (!raw_data)
return -ENOMEM; return -ENOMEM;

View File

@@ -662,7 +662,7 @@ static int bpf_core_calc_field_relo(const char *prog_name,
*validate = true; /* signedness is never ambiguous */ *validate = true; /* signedness is never ambiguous */
break; break;
case BPF_FIELD_LSHIFT_U64: case BPF_FIELD_LSHIFT_U64:
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #if __BYTE_ORDER == __LITTLE_ENDIAN
*val = 64 - (bit_off + bit_sz - byte_off * 8); *val = 64 - (bit_off + bit_sz - byte_off * 8);
#else #else
*val = (8 - byte_sz) * 8 + (bit_off - byte_off * 8); *val = (8 - byte_sz) * 8 + (bit_off - byte_off * 8);

View File

@@ -300,7 +300,7 @@ int xsk_umem__create_v0_0_4(struct xsk_umem **umem_ptr, void *umem_area,
if (!umem) if (!umem)
return -ENOMEM; return -ENOMEM;
umem->fd = socket(AF_XDP, SOCK_RAW | SOCK_CLOEXEC, 0); umem->fd = socket(AF_XDP, SOCK_RAW, 0);
if (umem->fd < 0) { if (umem->fd < 0) {
err = -errno; err = -errno;
goto out_umem_alloc; goto out_umem_alloc;
@@ -549,7 +549,7 @@ static int xsk_get_max_queues(struct xsk_socket *xsk)
struct ifreq ifr = {}; struct ifreq ifr = {};
int fd, err, ret; int fd, err, ret;
fd = socket(AF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0); fd = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (fd < 0) if (fd < 0)
return -errno; return -errno;
@@ -1046,7 +1046,7 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
} }
if (umem->refcount++ > 0) { if (umem->refcount++ > 0) {
xsk->fd = socket(AF_XDP, SOCK_RAW | SOCK_CLOEXEC, 0); xsk->fd = socket(AF_XDP, SOCK_RAW, 0);
if (xsk->fd < 0) { if (xsk->fd < 0) {
err = -errno; err = -errno;
goto out_xsk_alloc; goto out_xsk_alloc;

View File

@@ -23,12 +23,6 @@
extern "C" { extern "C" {
#endif #endif
/* This whole API has been deprecated and moved to libxdp that can be found at
* https://github.com/xdp-project/xdp-tools. The APIs are exactly the same so
* it should just be linking with libxdp instead of libbpf for this set of
* functionality. If not, please submit a bug report on the aforementioned page.
*/
/* Load-Acquire Store-Release barriers used by the XDP socket /* Load-Acquire Store-Release barriers used by the XDP socket
* library. The following macros should *NOT* be considered part of * library. The following macros should *NOT* be considered part of
* the xsk.h API, and is subject to change anytime. * the xsk.h API, and is subject to change anytime.
@@ -251,10 +245,8 @@ static inline __u64 xsk_umem__add_offset_to_addr(__u64 addr)
return xsk_umem__extract_addr(addr) + xsk_umem__extract_offset(addr); return xsk_umem__extract_addr(addr) + xsk_umem__extract_offset(addr);
} }
LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "AF_XDP support deprecated and moved to libxdp") LIBBPF_API int xsk_umem__fd(const struct xsk_umem *umem);
int xsk_umem__fd(const struct xsk_umem *umem); LIBBPF_API int xsk_socket__fd(const struct xsk_socket *xsk);
LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "AF_XDP support deprecated and moved to libxdp")
int xsk_socket__fd(const struct xsk_socket *xsk);
#define XSK_RING_CONS__DEFAULT_NUM_DESCS 2048 #define XSK_RING_CONS__DEFAULT_NUM_DESCS 2048
#define XSK_RING_PROD__DEFAULT_NUM_DESCS 2048 #define XSK_RING_PROD__DEFAULT_NUM_DESCS 2048
@@ -271,10 +263,10 @@ struct xsk_umem_config {
__u32 flags; __u32 flags;
}; };
LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "AF_XDP support deprecated and moved to libxdp") LIBBPF_API int xsk_setup_xdp_prog(int ifindex,
int xsk_setup_xdp_prog(int ifindex, int *xsks_map_fd); int *xsks_map_fd);
LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "AF_XDP support deprecated and moved to libxdp") LIBBPF_API int xsk_socket__update_xskmap(struct xsk_socket *xsk,
int xsk_socket__update_xskmap(struct xsk_socket *xsk, int xsks_map_fd); int xsks_map_fd);
/* Flags for the libbpf_flags field. */ /* Flags for the libbpf_flags field. */
#define XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD (1 << 0) #define XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD (1 << 0)
@@ -288,46 +280,40 @@ struct xsk_socket_config {
}; };
/* Set config to NULL to get the default configuration. */ /* Set config to NULL to get the default configuration. */
LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "AF_XDP support deprecated and moved to libxdp") LIBBPF_API int xsk_umem__create(struct xsk_umem **umem,
int xsk_umem__create(struct xsk_umem **umem, void *umem_area, __u64 size,
void *umem_area, __u64 size, struct xsk_ring_prod *fill,
struct xsk_ring_prod *fill, struct xsk_ring_cons *comp,
struct xsk_ring_cons *comp, const struct xsk_umem_config *config);
const struct xsk_umem_config *config); LIBBPF_API int xsk_umem__create_v0_0_2(struct xsk_umem **umem,
LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "AF_XDP support deprecated and moved to libxdp") void *umem_area, __u64 size,
int xsk_umem__create_v0_0_2(struct xsk_umem **umem, struct xsk_ring_prod *fill,
void *umem_area, __u64 size, struct xsk_ring_cons *comp,
struct xsk_ring_prod *fill, const struct xsk_umem_config *config);
struct xsk_ring_cons *comp, LIBBPF_API int xsk_umem__create_v0_0_4(struct xsk_umem **umem,
const struct xsk_umem_config *config); void *umem_area, __u64 size,
LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "AF_XDP support deprecated and moved to libxdp") struct xsk_ring_prod *fill,
int xsk_umem__create_v0_0_4(struct xsk_umem **umem, struct xsk_ring_cons *comp,
void *umem_area, __u64 size, const struct xsk_umem_config *config);
struct xsk_ring_prod *fill, LIBBPF_API int xsk_socket__create(struct xsk_socket **xsk,
struct xsk_ring_cons *comp, const char *ifname, __u32 queue_id,
const struct xsk_umem_config *config); struct xsk_umem *umem,
LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "AF_XDP support deprecated and moved to libxdp") struct xsk_ring_cons *rx,
int xsk_socket__create(struct xsk_socket **xsk, struct xsk_ring_prod *tx,
const char *ifname, __u32 queue_id, const struct xsk_socket_config *config);
struct xsk_umem *umem, LIBBPF_API int
struct xsk_ring_cons *rx, xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
struct xsk_ring_prod *tx, const char *ifname,
const struct xsk_socket_config *config); __u32 queue_id, struct xsk_umem *umem,
LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "AF_XDP support deprecated and moved to libxdp") struct xsk_ring_cons *rx,
int xsk_socket__create_shared(struct xsk_socket **xsk_ptr, struct xsk_ring_prod *tx,
const char *ifname, struct xsk_ring_prod *fill,
__u32 queue_id, struct xsk_umem *umem, struct xsk_ring_cons *comp,
struct xsk_ring_cons *rx, const struct xsk_socket_config *config);
struct xsk_ring_prod *tx,
struct xsk_ring_prod *fill,
struct xsk_ring_cons *comp,
const struct xsk_socket_config *config);
/* Returns 0 for success and -EBUSY if the umem is still in use. */ /* Returns 0 for success and -EBUSY if the umem is still in use. */
LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "AF_XDP support deprecated and moved to libxdp") LIBBPF_API int xsk_umem__delete(struct xsk_umem *umem);
int xsk_umem__delete(struct xsk_umem *umem); LIBBPF_API void xsk_socket__delete(struct xsk_socket *xsk);
LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "AF_XDP support deprecated and moved to libxdp")
void xsk_socket__delete(struct xsk_socket *xsk);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */