Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: new(libs): replace elfutils/libelf with elftoolchain/libelf #2174

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .clang-format-ignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ driver/syscall_compat_s390x.h
driver/syscall_compat_x86_64.h
driver/syscall_ia32_64_map.c
driver/syscall_table.c
# All third party code is not formatted
./contrib
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
steps:
- name: Install deps ⛓️
run: |
apk add g++ gcc cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils clang llvm
apk add g++ gcc cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils clang llvm bsd-compat-headers
git clone https://github.com/libbpf/bpftool.git --branch v7.3.0 --single-branch
cd bpftool
git submodule update --init
Expand Down Expand Up @@ -345,7 +345,7 @@ jobs:
- name: Install deps ⛓️
run: |
sudo apt update
sudo apt install -y --no-install-recommends ca-certificates cmake build-essential clang-14 llvm-14 git pkg-config autoconf automake libtool libelf-dev libcap-dev linux-headers-$(uname -r) emscripten
sudo apt install -y --no-install-recommends ca-certificates cmake build-essential clang-14 llvm-14 git pkg-config autoconf automake libtool libcap-dev linux-headers-$(uname -r) emscripten libc6-dev

- name: Checkout Libs ⤵️
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
Expand Down
1 change: 1 addition & 0 deletions .semgrepignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
contrib/
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ if(BUILD_SHARED_LIBS)
message(STATUS "Shared library soversion: ${FALCOSECURITY_SHARED_LIBS_SOVERSION}")
endif()

add_subdirectory(contrib/elftoolchain)

include(libscap)
include(libsinsp)

Expand Down
34 changes: 16 additions & 18 deletions cmake/modules/libbpf.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,42 +13,45 @@
# the License.
#

option(USE_BUNDLED_LIBBPF "Enable building of the bundled libbpf" ${USE_BUNDLED_DEPS})

if(LIBBPF_INCLUDE)
# we already have libbpf
elseif(NOT USE_BUNDLED_LIBBPF)
find_path(LIBBPF_INCLUDE bpf/libbpf.h)
find_library(LIBBPF_LIB NAMES bpf)
if(LIBBPF_INCLUDE AND LIBBPF_LIB)
message(STATUS "Found libbpf: include: ${LIBBPF_INCLUDE}, lib: ${LIBBPF_LIB}")
else()
message(FATAL_ERROR "Couldn't find system libbpf")
endif()
else()
include(zlib)
include(libelf)
set(LIBBPF_SRC "${PROJECT_BINARY_DIR}/libbpf-prefix/src")
set(LIBBPF_BUILD_DIR "${LIBBPF_SRC}/libbpf-build")
set(LIBBPF_INCLUDE "${LIBBPF_BUILD_DIR}/root/usr/include")
set(LIBBPF_LIB "${LIBBPF_BUILD_DIR}/root/usr/lib64/libbpf.a")

get_target_property(LIBELF_INCLUDE_DIR elf INCLUDE_DIRECTORIES)

foreach(dir ${LIBELF_INCLUDE_DIR})
string(APPEND LIBELF_COMPILER_STRING "-I${dir} ")
endforeach()

ExternalProject_Add(
libbpf
PREFIX "${PROJECT_BINARY_DIR}/libbpf-prefix"
DEPENDS zlib libelf
DEPENDS zlib elf
URL "https://github.com/libbpf/libbpf/archive/refs/tags/v1.3.0.tar.gz"
URL_HASH "SHA256=11db86acd627e468bc48b7258c1130aba41a12c4d364f78e184fd2f5a913d861"
CONFIGURE_COMMAND mkdir -p build root
BUILD_COMMAND
make BUILD_STATIC_ONLY=y OBJDIR=${LIBBPF_BUILD_DIR}/build
DESTDIR=${LIBBPF_BUILD_DIR}/root NO_PKG_CONFIG=1
"EXTRA_CFLAGS=-fPIC -I${LIBELF_INCLUDE} -I${ZLIB_INCLUDE}" "LDFLAGS=-Wl,-Bstatic"
"EXTRA_CFLAGS=-fPIC ${LIBELF_COMPILER_STRING} -I${ZLIB_INCLUDE}" "LDFLAGS=-Wl,-Bstatic"
"EXTRA_LDFLAGS=-L${LIBELF_SRC}/libelf/libelf -L${ZLIB_SRC}" -C ${LIBBPF_SRC}/libbpf/src
install install_uapi_headers
INSTALL_COMMAND ""
UPDATE_COMMAND ""
BUILD_BYPRODUCTS ${LIBBPF_LIB}
)

add_library(lbpf STATIC IMPORTED)
set_target_properties(lbpf PROPERTIES IMPORTED_LOCATION ${LIBBPF_LIB})
file(MAKE_DIRECTORY ${LIBBPF_INCLUDE}) # necessary to make target_include_directories() work
target_include_directories(lbpf INTERFACE ${LIBBPF_INCLUDE})
target_link_libraries(lbpf INTERFACE elf ${ZLIB_LIB})

message(STATUS "Using bundled libbpf: include'${LIBBPF_INCLUDE}', lib: ${LIBBPF_LIB}")
install(
FILES "${LIBBPF_LIB}"
Expand All @@ -57,8 +60,3 @@ else()
)
endif()

if(NOT TARGET libbpf)
add_custom_target(libbpf)
endif()

include_directories(${LIBBPF_INCLUDE})
25 changes: 25 additions & 0 deletions contrib/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Contrib directory

This directory contains forks of some projects that may not be included as-is and require custom patches.

## Elftoolchain

This is the version of Elftoolchain (https://sourceforge.net/projects/elftoolchain/) that is used to satisfy the `libelf` requirement of the Falco libraries and its dependent `libbpf`.

This is how this fork was created:

* We downloaded the code from https://sourceforge.net/projects/elftoolchain/
* We precompiled the autogenerated files by running:

```sh
cd common/sys
m4 -I$(pwd) -D SRCDIR=$(pwd) elfdefinitions.m4 > elfdefinitions.h
cd ../../libelf
m4 -D SRCDIR=$(pwd) libelf_fsize.m4 > libelf_fsize.c
m4 -D SRCDIR=$(pwd) libelf_msize.m4 > libelf_msize.c
m4 -D SRCDIR=$(pwd) libelf_convert.m4 > libelf_convert.c
```

* We wrote `CMakeLists.txt` and `libelf/CMakeLists.txt` to enable CMake to build `libelf`
* We added compatibility patches `elf.h`, `gelf_getnote.c`, `gelf_versym.c` and modified `gelf.h`, `libelf.h` to make this flavor of libelf work with libbpf
* This way, a new target `elf` is built and can be linked via `target_link_libraries()`
31 changes: 31 additions & 0 deletions contrib/elftoolchain/.cirrus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
env:
CIRRUS_CLONE_DEPTH: 1

freebsd_task:
freebsd_instance:
matrix:
image: freebsd-11-2-release-amd64
image: freebsd-12-1-release-amd64
install_script: pkg install -y git py27-yaml
script:
- fetch http://tetworks.opengroup.org/downloads/38/software/Sources/3.8/tet3.8-src.tar.gz
- tar -x -C test/tet -f tet3.8-src.tar.gz
- make
test_script:
- make run-tests

ubuntu_task:
container:
image: ubuntu:18.04
setup_script:
- apt-get update
- apt-get install -y
binutils bison bmake curl flex g++ gcc git
libarchive-dev libbsd-dev libc6-dev libexpat1-dev lsb-release
m4 perl python-yaml sharutils zlib1g-dev
script:
- curl -O http://tetworks.opengroup.org/downloads/38/software/Sources/3.8/tet3.8-src.tar.gz
- tar -x -C test/tet -z -f tet3.8-src.tar.gz
- bmake
test_script:
- bmake run-tests
217 changes: 217 additions & 0 deletions contrib/elftoolchain/.style.yapf
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
[style]
# Align closing bracket with visual indentation.
align_closing_bracket_with_visual_indent=True

# Allow dictionary keys to exist on multiple lines. For example:
#
# x = {
# ('this is the first element of a tuple',
# 'this is the second element of a tuple'):
# value,
# }
allow_multiline_dictionary_keys=False

# Allow lambdas to be formatted on more than one line.
allow_multiline_lambdas=True

# Allow splits before the dictionary value.
allow_split_before_dict_value=True

# Insert a blank line before a class-level docstring.
blank_line_before_class_docstring=False

# Insert a blank line before a 'def' or 'class' immediately nested
# within another 'def' or 'class'. For example:
#
# class Foo:
# # <------ this blank line
# def method():
# ...
blank_line_before_nested_class_or_def=True

# Do not split consecutive brackets. Only relevant when
# dedent_closing_brackets is set. For example:
#
# call_func_that_takes_a_dict(
# {
# 'key1': 'value1',
# 'key2': 'value2',
# }
# )
#
# would reformat to:
#
# call_func_that_takes_a_dict({
# 'key1': 'value1',
# 'key2': 'value2',
# })
coalesce_brackets=True

# The column limit.
column_limit=79

# Indent width used for line continuations.
continuation_indent_width=4

# Put closing brackets on a separate line, dedented, if the bracketed
# expression can't fit in a single line. Applies to all kinds of brackets,
# including function definitions and calls. For example:
#
# config = {
# 'key1': 'value1',
# 'key2': 'value2',
# } # <--- this bracket is dedented and on a separate line
#
# time_series = self.remote_client.query_entity_counters(
# entity='dev3246.region1',
# key='dns.query_latency_tcp',
# transform=Transformation.AVERAGE(window=timedelta(seconds=60)),
# start_ts=now()-timedelta(days=3),
# end_ts=now(),
# ) # <--- this bracket is dedented and on a separate line
dedent_closing_brackets=False

# Place each dictionary entry onto its own line.
each_dict_entry_on_separate_line=True

# The regex for an i18n comment. The presence of this comment stops
# reformatting of that line, because the comments are required to be
# next to the string they translate.
i18n_comment=

# The i18n function call names. The presence of this function stops
# reformattting on that line, because the string it has cannot be moved
# away from the i18n comment.
i18n_function_call=

# Indent the dictionary value if it cannot fit on the same line as the
# dictionary key. For example:
#
# config = {
# 'key1':
# 'value1',
# 'key2': value1 +
# value2,
# }
indent_dictionary_value=False

# The number of columns to use for indentation.
indent_width=4

# Join short lines into one line. E.g., single line 'if' statements.
join_multiple_lines=True

# Do not include spaces around selected binary operators. For example:
#
# 1 + 2 * 3 - 4 / 5
#
# will be formatted as follows when configured with a value "*,/":
#
# 1 + 2*3 - 4/5
#
no_spaces_around_selected_binary_operators=set()

# Use spaces around default or named assigns.
spaces_around_default_or_named_assign=False

# Use spaces around the power operator.
spaces_around_power_operator=False

# The number of spaces required before a trailing comment.
spaces_before_comment=2

# Insert a space between the ending comma and closing bracket of a list,
# etc.
space_between_ending_comma_and_closing_bracket=True

# Split before arguments if the argument list is terminated by a
# comma.
split_arguments_when_comma_terminated=False

# Set to True to prefer splitting before '&', '|' or '^' rather than
# after.
split_before_bitwise_operator=True

# Split before a dictionary or set generator (comp_for). For example, note
# the split before the 'for':
#
# foo = {
# variable: 'Hello world, have a nice day!'
# for variable in bar if variable != 42
# }
split_before_dict_set_generator=True

# Split after the opening paren which surrounds an expression if it doesn't
# fit on a single line.
split_before_expression_after_opening_paren=False

# If an argument / parameter list is going to be split, then split before
# the first argument.
split_before_first_argument=False

# Set to True to prefer splitting before 'and' or 'or' rather than
# after.
split_before_logical_operator=True

# Split named assignments onto individual lines.
split_before_named_assigns=True

# Set to True to split list comprehensions and generators that have
# non-trivial expressions and multiple clauses before each of these
# clauses. For example:
#
# result = [
# a_long_var + 100 for a_long_var in xrange(1000)
# if a_long_var % 10]
#
# would reformat to something like:
#
# result = [
# a_long_var + 100
# for a_long_var in xrange(1000)
# if a_long_var % 10]
split_complex_comprehension=False

# The penalty for splitting right after the opening bracket.
split_penalty_after_opening_bracket=30

# The penalty for splitting the line after a unary operator.
split_penalty_after_unary_operator=10000

# The penalty for splitting right before an if expression.
split_penalty_before_if_expr=0

# The penalty of splitting the line around the '&', '|', and '^'
# operators.
split_penalty_bitwise_operator=300

# The penalty for splitting a list comprehension or generator
# expression.
split_penalty_comprehension=80

# The penalty for characters over the column limit.
split_penalty_excess_character=4500

# The penalty incurred by adding a line split to the unwrapped line. The
# more line splits added the higher the penalty.
split_penalty_for_added_line_split=30

# The penalty of splitting a list of "import as" names. For example:
#
# from a_very_long_or_indented_module_name_yada_yad import (long_argument_1,
# long_argument_2,
# long_argument_3)
#
# would reformat to something like:
#
# from a_very_long_or_indented_module_name_yada_yad import (
# long_argument_1, long_argument_2, long_argument_3)
split_penalty_import_names=0

# The penalty of splitting the line around the 'and' and 'or'
# operators.
split_penalty_logical_operator=300

# Use the Tab character for indentation.
use_tabs=False

Loading
Loading