Skip to content

Commit

Permalink
use linux tools/lib/bpf as the core C library
Browse files Browse the repository at this point in the history
This patch brings https://github.com/libbpf/libbpf. The libbpf
is installed at src/cc/libbpf directory. The original files
src/cc/compat/linux/{bpf.h, bpf_common.h} are removed from
the repo. Instead, the corresponding files at
src/cc/libbpf/include/uapi/linux directory will be used.

libbpf will be periodically updated so that bcc can access latest linux
bpf/btf uapi headers and other newly added functionalities.
The following are the necessary steps to sync libbpf:
   1. copy https://github.com/libbpf/libbpf repo files into libbpf directory
      except .git file.
   2. sync compat/linux/virtual_bpf.h with libbpf/include/uapi/linux/bpf.h
      as virtual_bpf.h has an extra string wrapper for bpf.h.
   3. if new bpf.h has new helpers, add corresponding helper func define
      in bcc:src/cc/export/helpers.h and helper entry for error reporting
      in bcc:src/cc/libbpf.c.
   4. if new bpf.h has new map types, program types, update bcc:introspection/bps.c
      for these new map/program types.

This patch just brought in libbpf with top commit 556e0a0def95
("bpf: sync with latest bpf-next tree (#5)"), and made necessary changes
to use bpf.h and bpf_common.h files from src/cc/libbpf/include/uapi/linux
directory.

Signed-off-by: Yonghong Song <[email protected]>
  • Loading branch information
yonghong-song committed Nov 29, 2018
1 parent a07ab90 commit c07c05b
Show file tree
Hide file tree
Showing 37 changed files with 7,480 additions and 5 deletions.
1 change: 1 addition & 0 deletions examples/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

include_directories(${CMAKE_SOURCE_DIR}/src/cc)
include_directories(${CMAKE_SOURCE_DIR}/src/cc/api)
include_directories(${CMAKE_SOURCE_DIR}/src/cc/libbpf/include/uapi)

option(INSTALL_CPP_EXAMPLES "Install C++ examples. Those binaries are statically linked and can take plenty of disk space" OFF)

Expand Down
1 change: 1 addition & 0 deletions introspection/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

include_directories(${CMAKE_SOURCE_DIR}/src/cc)
include_directories(${CMAKE_SOURCE_DIR}/src/cc/api)
include_directories(${CMAKE_SOURCE_DIR}/src/cc/libbpf/include/uapi)

option(INSTALL_INTROSPECTION "Install BPF introspection tools" ON)

Expand Down
3 changes: 2 additions & 1 deletion src/cc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frontends/clang)
include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${LIBELF_INCLUDE_DIRS})
# todo: if check for kernel version
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/compat)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libbpf/include/uapi)
add_definitions(${LLVM_DEFINITIONS})
configure_file(libbcc.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libbcc.pc @ONLY)

Expand Down Expand Up @@ -100,6 +100,7 @@ install(TARGETS bcc-shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES ${bcc_table_headers} DESTINATION include/bcc)
install(FILES ${bcc_api_headers} DESTINATION include/bcc)
install(DIRECTORY compat/linux/ DESTINATION include/bcc/compat/linux FILES_MATCHING PATTERN "*.h")
install(DIRECTORY libbpf/include/uapi/linux/ DESTINATION include/bcc/compat/linux FILES_MATCHING PATTERN "*.h")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libbcc.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif(ENABLE_CLANG_JIT)
install(FILES ${bcc_common_headers} DESTINATION include/bcc)
Expand Down
18 changes: 18 additions & 0 deletions src/cc/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
The libbpf directory is regularly synced with https://github.com/libbpf/libbpf.
All the file under that repo will be copied into libbpf directory except .git directory.

If you have any change in libbpf/ directory, please upstream to linux first
as libbpf repo is a mirror of linux/tools/lib/bpf directory.

libbpf should be periodically updated so that bcc can access latest linux bpf/btf
uapi headers and other newly added functionalities. The following are the necessary
steps to sync libbpf:
1. copy https://github.com/libbpf/libbpf repo files into libbpf directory
except .git file.
2. sync compat/linux/virtual_bpf.h with libbpf/include/uapi/linux/bpf.h
as virtual_bpf.h has an extra string wrapper for bpf.h.
3. if new bpf.h has new helpers, add corresponding helper func define
in bcc:src/cc/export/helpers.h and helper entry for error reporting
in bcc:src/cc/libbpf.c.
4. if new bpf.h has new map types, program types, update bcc:introspection/bps.c
for these new map/program types.
2 changes: 1 addition & 1 deletion src/cc/api/BPF.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include "bcc_exception.h"
#include "bcc_syms.h"
#include "bpf_module.h"
#include "compat/linux/bpf.h"
#include "linux/bpf.h"
#include "libbpf.h"
#include "table_storage.h"

Expand Down
1 change: 1 addition & 0 deletions src/cc/compat/linux/virtual_bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -2469,6 +2469,7 @@ struct __sk_buff {

__u32 data_meta;
struct bpf_flow_keys *flow_keys;
__u64 tstamp;
};

struct bpf_tunnel_key {
Expand Down
2 changes: 1 addition & 1 deletion src/cc/libbpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#ifndef LIBBPF_H
#define LIBBPF_H

#include "compat/linux/bpf.h"
#include "linux/bpf.h"
#include <stdint.h>
#include <sys/types.h>

Expand Down
31 changes: 31 additions & 0 deletions src/cc/libbpf/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

This is a mirror of bpf-next linux tree
(https://kernel.googlesource.com/pub/scm/linux/kernel/git/bpf/bpf-next)
bpf-next/tools/lib/bpf directory plus its supporting header files.

The following files will by sync'ed with bpf-next repo:
src/ <-> bpf-next/tools/lib/bpf/
include/uapi/linux/bpf_common.h <-> bpf-next/tools/include/uapi/linux/bpf_common.h
include/uapi/linux/bpf.h <-> bpf-next/tools/include/uapi/linux/bpf.h
include/uapi/linux/btf.h <-> bpf-next/tools/include/uapi/linux/btf.h
include/uapi/linux/if_link.h <-> bpf-next/tools/include/uapi/linux/if_link.h
include/uapi/linux/netlink.h <-> bpf-next/tools/include/uapi/linux/netlink.h
include/tools/libc_compat.h <-> bpf-next/tools/include/tools/libc_compat.h

Other header files at this repo (include/linux/*.h) are reduced versions of
their counterpart files at bpf-next/tools/include/linux/*.h to make compilation
successful.

Build
=====

To build static library libbpf.a:
cd src
make

To build both static libbpf.a and shared libbpf.so libraries in directory
build/ and install them together with libbpf headers in a staging directory
root/:
cd src
mkdir build root
BUILD_SHARED=y OBJDIR=build DESTDIR=root make install
32 changes: 32 additions & 0 deletions src/cc/libbpf/include/linux/err.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */

#ifndef __LINUX_ERR_H
#define __LINUX_ERR_H

#include <linux/types.h>

#define MAX_ERRNO 4095

#define IS_ERR_VALUE(x) ((x) >= (unsigned long)-MAX_ERRNO)

static inline void * ERR_PTR(long error_)
{
return (void *) error_;
}

static inline long PTR_ERR(const void *ptr)
{
return (long) ptr;
}

static inline bool IS_ERR(const void *ptr)
{
return IS_ERR_VALUE((unsigned long)ptr);
}

static inline bool IS_ERR_OR_NULL(const void *ptr)
{
return (!ptr) || IS_ERR_VALUE((unsigned long)ptr);
}

#endif
24 changes: 24 additions & 0 deletions src/cc/libbpf/include/linux/filter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */

#ifndef __LINUX_FILTER_H
#define __LINUX_FILTER_H

#include <linux/bpf.h>

#define BPF_MOV64_IMM(DST, IMM) \
((struct bpf_insn) { \
.code = BPF_ALU64 | BPF_MOV | BPF_K, \
.dst_reg = DST, \
.src_reg = 0, \
.off = 0, \
.imm = IMM })

#define BPF_EXIT_INSN() \
((struct bpf_insn) { \
.code = BPF_JMP | BPF_EXIT, \
.dst_reg = 0, \
.src_reg = 0, \
.off = 0, \
.imm = 0 })

#endif
43 changes: 43 additions & 0 deletions src/cc/libbpf/include/linux/kernel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */

#ifndef __LINUX_KERNEL_H
#define __LINUX_KERNEL_H

#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

#ifndef container_of
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
#endif

#ifndef max
#define max(x, y) ({ \
typeof(x) _max1 = (x); \
typeof(y) _max2 = (y); \
(void) (&_max1 == &_max2); \
_max1 > _max2 ? _max1 : _max2; })
#endif

#ifndef min
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
#endif

#ifndef roundup
#define roundup(x, y) ( \
{ \
const typeof(y) __y = y; \
(((x) + (__y - 1)) / __y) * __y; \
} \
)
#endif

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

#endif
82 changes: 82 additions & 0 deletions src/cc/libbpf/include/linux/list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */

#ifndef __LINUX_LIST_H
#define __LINUX_LIST_H

#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)

#define POISON_POINTER_DELTA 0
#define LIST_POISON1 ((void *) 0x100 + POISON_POINTER_DELTA)
#define LIST_POISON2 ((void *) 0x200 + POISON_POINTER_DELTA)


static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}

static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}

/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}

/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}

/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void __list_del_entry(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
}

static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}

#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
#define list_next_entry(pos, member) \
list_entry((pos)->member.next, typeof(*(pos)), member)

#endif
90 changes: 90 additions & 0 deletions src/cc/libbpf/include/linux/overflow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */

#ifndef __LINUX_OVERFLOW_H
#define __LINUX_OVERFLOW_H

#define is_signed_type(type) (((type)(-1)) < (type)1)
#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
#define type_min(T) ((T)((T)-type_max(T)-(T)1))

#ifndef unlikely
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif

#ifdef __GNUC__
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#if GCC_VERSION >= 50100
#define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
#endif
#endif

#ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW

#define check_mul_overflow(a, b, d) ({ \
typeof(a) __a = (a); \
typeof(b) __b = (b); \
typeof(d) __d = (d); \
(void) (&__a == &__b); \
(void) (&__a == __d); \
__builtin_mul_overflow(__a, __b, __d); \
})

#else

/*
* If one of a or b is a compile-time constant, this avoids a division.
*/
#define __unsigned_mul_overflow(a, b, d) ({ \
typeof(a) __a = (a); \
typeof(b) __b = (b); \
typeof(d) __d = (d); \
(void) (&__a == &__b); \
(void) (&__a == __d); \
*__d = __a * __b; \
__builtin_constant_p(__b) ? \
__b > 0 && __a > type_max(typeof(__a)) / __b : \
__a > 0 && __b > type_max(typeof(__b)) / __a; \
})

/*
* Signed multiplication is rather hard. gcc always follows C99, so
* division is truncated towards 0. This means that we can write the
* overflow check like this:
*
* (a > 0 && (b > MAX/a || b < MIN/a)) ||
* (a < -1 && (b > MIN/a || b < MAX/a) ||
* (a == -1 && b == MIN)
*
* The redundant casts of -1 are to silence an annoying -Wtype-limits
* (included in -Wextra) warning: When the type is u8 or u16, the
* __b_c_e in check_mul_overflow obviously selects
* __unsigned_mul_overflow, but unfortunately gcc still parses this
* code and warns about the limited range of __b.
*/

#define __signed_mul_overflow(a, b, d) ({ \
typeof(a) __a = (a); \
typeof(b) __b = (b); \
typeof(d) __d = (d); \
typeof(a) __tmax = type_max(typeof(a)); \
typeof(a) __tmin = type_min(typeof(a)); \
(void) (&__a == &__b); \
(void) (&__a == __d); \
*__d = (__u64)__a * (__u64)__b; \
(__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) || \
(__b < (typeof(__b))-1 && (__a > __tmin/__b || __a < __tmax/__b)) || \
(__b == (typeof(__b))-1 && __a == __tmin); \
})

#define check_mul_overflow(a, b, d) \
__builtin_choose_expr(is_signed_type(typeof(a)), \
__signed_mul_overflow(a, b, d), \
__unsigned_mul_overflow(a, b, d))


#endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */

#endif
Loading

0 comments on commit c07c05b

Please sign in to comment.