Skip to content

Commit

Permalink
Add test pass to run bpf_conformance with ELF
Browse files Browse the repository at this point in the history
Signed-off-by: Alan Jowett <alanjo@microsoft.com>

Fix build on platforms without elf

Signed-off-by: Alan Jowett <alanjo@microsoft.com>

Skip ELF on aarch64 cross-compile

Signed-off-by: Alan Jowett <alanjo@microsoft.com>
  • Loading branch information
Alan-Jowett authored and Alan Jowett committed Nov 27, 2023
1 parent 274cf83 commit 7e1accd
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 21 deletions.
8 changes: 8 additions & 0 deletions CMakeLists.txt
Expand Up @@ -21,6 +21,14 @@ include("cmake/settings.cmake")
include("cmake/options.cmake")
include("cmake/version.cmake")

find_path(UBPF_ELF_H_PATH "elf.h" NO_CACHE)
if(UBPF_ELF_H_PATH)
set(UBPF_HAS_ELF_H true)

else()
message(WARNING "ubpf - elf.h was not found, disabling ELF support")
endif()

if(UBPF_ENABLE_TESTS)
include("CTest")
endif()
Expand Down
20 changes: 20 additions & 0 deletions ubpf_plugin/CMakeLists.txt
Expand Up @@ -80,4 +80,24 @@ foreach(file ${files})
if(EXPECT_FAILURE)
set_tests_properties(${file}-Interpreter PROPERTIES WILL_FAIL TRUE)
endif()

if(UBPF_ELF_H_PATH AND NOT CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
add_test(
NAME ${file}-JIT-ELF
COMMAND ${BPF_CONFORMANCE_RUNNER} --elf true --test_file_path ${file} ${PLUGIN_JIT}
)

if(EXPECT_FAILURE)
set_tests_properties(${file}-JIT-ELF PROPERTIES WILL_FAIL TRUE)
endif()

add_test(
NAME ${file}-Interpreter-ELF
COMMAND ${BPF_CONFORMANCE_RUNNER} --elf true --test_file_path ${file} ${PLUGIN_INTERPRET}
)

if(EXPECT_FAILURE)
set_tests_properties(${file}-Interpreter-ELF PROPERTIES WILL_FAIL TRUE)
endif()
endif()
endforeach()
49 changes: 29 additions & 20 deletions ubpf_plugin/ubpf_plugin.cc
Expand Up @@ -48,20 +48,6 @@ base16_decode(const std::string &input)
return output;
}

/**
* @brief Convert a vector of bytes to a vector of ebpf_inst.
*
* @param[in] bytes Vector of bytes.
* @return Vector of ebpf_inst.
*/
std::vector<ebpf_inst>
bytes_to_ebpf_inst(std::vector<uint8_t> bytes)
{
std::vector<ebpf_inst> instructions(bytes.size() / sizeof(ebpf_inst));
memcpy(instructions.data(), bytes.data(), bytes.size());
return instructions;
}

/**
* @brief This program reads BPF instructions from stdin and memory contents from
* the first agument. It then executes the BPF program and prints the
Expand All @@ -70,6 +56,7 @@ bytes_to_ebpf_inst(std::vector<uint8_t> bytes)
int main(int argc, char **argv)
{
bool jit = false; // JIT == true, interpreter == false
bool is_elf = false;
std::vector<std::string> args(argv, argv + argc);
std::string program_string;
std::string memory_string;
Expand Down Expand Up @@ -102,6 +89,12 @@ int main(int argc, char **argv)
jit = false;
args.erase(args.begin());
}
#if defined(UBPF_HAS_ELF_H)
if (args.size() > 0 && args[0] == "--elf") {
is_elf = true;
args.erase(args.begin());
}
#endif

if (args.size() > 0 && args[0].size() > 0)
{
Expand All @@ -113,7 +106,7 @@ int main(int argc, char **argv)
std::getline(std::cin, program_string);
}

std::vector<ebpf_inst> program = bytes_to_ebpf_inst(base16_decode(program_string));
auto program_byte = base16_decode(program_string);
std::vector<uint8_t> memory = base16_decode(memory_string);

std::unique_ptr<ubpf_vm, decltype(&ubpf_destroy)> vm(ubpf_create(), ubpf_destroy);
Expand All @@ -140,12 +133,28 @@ int main(int argc, char **argv)
return 1;
}

if (ubpf_load(vm.get(), program.data(), static_cast<uint32_t>(program.size() * sizeof(ebpf_inst)), &error) != 0)
{
std::cerr << "Failed to load program: " << error << std::endl;
std::cout << "Failed to load code: " << error << std::endl;
free(error);
if (is_elf) {
#if defined(UBPF_HAS_ELF_H)
if (ubpf_load_elf(vm.get(), program_byte.data(), static_cast<uint32_t>(program_byte.size()), &error) != 0)
{
std::cerr << "Failed to load program: " << error << std::endl;
std::cout << "Failed to load code: " << error << std::endl;
free(error);
return 1;
}
#else
std::cerr << "ELF support not compiled in" << std::endl;
return 1;
#endif
}
else {
if (ubpf_load(vm.get(), program_byte.data(), static_cast<uint32_t>(program_byte.size()), &error) != 0)
{
std::cerr << "Failed to load program: " << error << std::endl;
std::cout << "Failed to load code: " << error << std::endl;
free(error);
return 1;
}
}

uint64_t actual_result;
Expand Down
1 change: 0 additions & 1 deletion vm/CMakeLists.txt
@@ -1,6 +1,5 @@
# Copyright (c) 2022-present, IO Visor Project
# SPDX-License-Identifier: Apache-2.0

#
# Copyright (c) 2022-present, IO Visor Project
# All rights reserved.
Expand Down

0 comments on commit 7e1accd

Please sign in to comment.