Skip to content

Commit

Permalink
Cleanup - test ELFs (#604)
Browse files Browse the repository at this point in the history
* Makes cargo fmt happy.

* Remove SBPF-v2 only test ELFs.

* Move test_struct_func_pointer.

* Explicitly marks SBPF-v1 ELF tests as such.

* Moves test_err_unresolved_syscall_reloc_64_32.
  • Loading branch information
Lichtso authored Oct 7, 2024
1 parent c8b1cd6 commit c06f051
Show file tree
Hide file tree
Showing 20 changed files with 99 additions and 189 deletions.
11 changes: 1 addition & 10 deletions benches/elf_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,7 @@ fn loader() -> Arc<BuiltinProgram<TestContextObject>> {

#[bench]
fn bench_load_sbpfv1(bencher: &mut Bencher) {
let mut file = File::open("tests/elfs/syscall_reloc_64_32.so").unwrap();
let mut elf = Vec::new();
file.read_to_end(&mut elf).unwrap();
let loader = loader();
bencher.iter(|| Executable::<TestContextObject>::from_elf(&elf, loader.clone()).unwrap());
}

#[bench]
fn bench_load_sbpfv2(bencher: &mut Bencher) {
let mut file = File::open("tests/elfs/syscall_static.so").unwrap();
let mut file = File::open("tests/elfs/syscall_reloc_64_32_sbpfv1.so").unwrap();
let mut elf = Vec::new();
file.read_to_end(&mut elf).unwrap();
let loader = loader();
Expand Down
4 changes: 2 additions & 2 deletions benches/jit_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use test_utils::create_vm;

#[bench]
fn bench_init_vm(bencher: &mut Bencher) {
let mut file = File::open("tests/elfs/relative_call.so").unwrap();
let mut file = File::open("tests/elfs/relative_call_sbpfv1.so").unwrap();
let mut elf = Vec::new();
file.read_to_end(&mut elf).unwrap();
let executable =
Expand All @@ -42,7 +42,7 @@ fn bench_init_vm(bencher: &mut Bencher) {
#[cfg(all(feature = "jit", not(target_os = "windows"), target_arch = "x86_64"))]
#[bench]
fn bench_jit_compile(bencher: &mut Bencher) {
let mut file = File::open("tests/elfs/relative_call.so").unwrap();
let mut file = File::open("tests/elfs/relative_call_sbpfv1.so").unwrap();
let mut elf = Vec::new();
file.read_to_end(&mut elf).unwrap();
let mut executable =
Expand Down
4 changes: 2 additions & 2 deletions benches/vm_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use test_utils::create_vm;

#[bench]
fn bench_init_interpreter_start(bencher: &mut Bencher) {
let mut file = File::open("tests/elfs/rodata_section.so").unwrap();
let mut file = File::open("tests/elfs/rodata_section_sbpfv1.so").unwrap();
let mut elf = Vec::new();
file.read_to_end(&mut elf).unwrap();
let executable =
Expand All @@ -51,7 +51,7 @@ fn bench_init_interpreter_start(bencher: &mut Bencher) {
#[cfg(all(feature = "jit", not(target_os = "windows"), target_arch = "x86_64"))]
#[bench]
fn bench_init_jit_start(bencher: &mut Bencher) {
let mut file = File::open("tests/elfs/rodata_section.so").unwrap();
let mut file = File::open("tests/elfs/rodata_section_sbpfv1.so").unwrap();
let mut elf = Vec::new();
file.read_to_end(&mut elf).unwrap();
let mut executable =
Expand Down
46 changes: 31 additions & 15 deletions src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1182,7 +1182,7 @@ mod test {

#[test]
fn test_validate() {
let elf_bytes = std::fs::read("tests/elfs/relative_call.so").unwrap();
let elf_bytes = std::fs::read("tests/elfs/relative_call_sbpfv1.so").unwrap();
let elf = Elf64::parse(&elf_bytes).unwrap();
let mut header = elf.file_header().clone();

Expand Down Expand Up @@ -1244,7 +1244,7 @@ mod test {

#[test]
fn test_load() {
let mut file = File::open("tests/elfs/relative_call.so").expect("file open failed");
let mut file = File::open("tests/elfs/relative_call_sbpfv1.so").expect("file open failed");
let mut elf_bytes = Vec::new();
file.read_to_end(&mut elf_bytes)
.expect("failed to read elf file");
Expand All @@ -1254,7 +1254,7 @@ mod test {
#[test]
fn test_load_unaligned() {
let mut elf_bytes =
std::fs::read("tests/elfs/relative_call.so").expect("failed to read elf file");
std::fs::read("tests/elfs/relative_call_sbpfv1.so").expect("failed to read elf file");
// The default allocator allocates aligned memory. Move the ELF slice to
// elf_bytes.as_ptr() + 1 to make it unaligned and test unaligned
// parsing.
Expand All @@ -1266,14 +1266,14 @@ mod test {
fn test_entrypoint() {
let loader = loader();

let mut file = File::open("tests/elfs/syscall_static.so").expect("file open failed");
let mut file = File::open("tests/elfs/relative_call_sbpfv1.so").expect("file open failed");
let mut elf_bytes = Vec::new();
file.read_to_end(&mut elf_bytes)
.expect("failed to read elf file");
let elf = ElfExecutable::load(&elf_bytes, loader.clone()).expect("validation failed");
let parsed_elf = Elf64::parse(&elf_bytes).unwrap();
let executable: &Executable<TestContextObject> = &elf;
assert_eq!(0, executable.get_entrypoint_instruction_offset());
assert_eq!(4, executable.get_entrypoint_instruction_offset());

let write_header = |header: Elf64Ehdr| unsafe {
let mut bytes = elf_bytes.clone();
Expand All @@ -1288,7 +1288,7 @@ mod test {
let elf_bytes = write_header(header.clone());
let elf = ElfExecutable::load(&elf_bytes, loader.clone()).expect("validation failed");
let executable: &Executable<TestContextObject> = &elf;
assert_eq!(1, executable.get_entrypoint_instruction_offset());
assert_eq!(5, executable.get_entrypoint_instruction_offset());

header.e_entry = 1;
let elf_bytes = write_header(header.clone());
Expand All @@ -1315,7 +1315,7 @@ mod test {
let elf_bytes = write_header(header);
let elf = ElfExecutable::load(&elf_bytes, loader).expect("validation failed");
let executable: &Executable<TestContextObject> = &elf;
assert_eq!(0, executable.get_entrypoint_instruction_offset());
assert_eq!(4, executable.get_entrypoint_instruction_offset());
}

#[test]
Expand Down Expand Up @@ -1878,15 +1878,15 @@ mod test {
#[should_panic(expected = r#"validation failed: WritableSectionNotSupported(".data")"#)]
fn test_writable_data_section() {
let elf_bytes =
std::fs::read("tests/elfs/data_section.so").expect("failed to read elf file");
std::fs::read("tests/elfs/data_section_sbpfv1.so").expect("failed to read elf file");
ElfExecutable::load(&elf_bytes, loader()).expect("validation failed");
}

#[test]
#[should_panic(expected = r#"validation failed: WritableSectionNotSupported(".bss")"#)]
fn test_bss_section() {
let elf_bytes =
std::fs::read("tests/elfs/bss_section.so").expect("failed to read elf file");
std::fs::read("tests/elfs/bss_section_sbpfv1.so").expect("failed to read elf file");
ElfExecutable::load(&elf_bytes, loader()).expect("validation failed");
}

Expand All @@ -1899,23 +1899,39 @@ mod test {
}

#[test]
#[should_panic(expected = "validation failed: RelativeJumpOutOfBounds(9)")]
#[should_panic(expected = "validation failed: RelativeJumpOutOfBounds(8)")]
fn test_relative_call_oob_backward() {
let mut elf_bytes =
std::fs::read("tests/elfs/relative_call.so").expect("failed to read elf file");
LittleEndian::write_i32(&mut elf_bytes[0x104C..0x1050], -11i32);
std::fs::read("tests/elfs/relative_call_sbpfv1.so").expect("failed to read elf file");
LittleEndian::write_i32(&mut elf_bytes[0x1044..0x1048], -11i32);
ElfExecutable::load(&elf_bytes, loader()).expect("validation failed");
}

#[test]
#[should_panic(expected = "validation failed: RelativeJumpOutOfBounds(12)")]
#[should_panic(expected = "validation failed: RelativeJumpOutOfBounds(11)")]
fn test_relative_call_oob_forward() {
let mut elf_bytes =
std::fs::read("tests/elfs/relative_call.so").expect("failed to read elf file");
LittleEndian::write_i32(&mut elf_bytes[0x1064..0x1068], 5);
std::fs::read("tests/elfs/relative_call_sbpfv1.so").expect("failed to read elf file");
LittleEndian::write_i32(&mut elf_bytes[0x105C..0x1060], 5);
ElfExecutable::load(&elf_bytes, loader()).expect("validation failed");
}

#[test]
#[should_panic(expected = "validation failed: UnresolvedSymbol(\"log\", 39, 312)")]
fn test_err_unresolved_syscall_reloc_64_32() {
let loader = BuiltinProgram::new_loader(
Config {
enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1,
reject_broken_elfs: true,
..Config::default()
},
FunctionRegistry::default(),
);
let elf_bytes = std::fs::read("tests/elfs/syscall_reloc_64_32_sbpfv1.so")
.expect("failed to read elf file");
ElfExecutable::load(&elf_bytes, Arc::new(loader)).expect("validation failed");
}

#[test]
fn test_long_section_name() {
let elf_bytes = std::fs::read("tests/elfs/long_section_name.so").unwrap();
Expand Down
2 changes: 1 addition & 1 deletion src/elf_parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ impl<'a> Elf64<'a> {
}
}

impl<'a> fmt::Debug for Elf64<'a> {
impl fmt::Debug for Elf64<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "{:#X?}", self.file_header)?;
for program_header in self.program_header_table.iter() {
Expand Down
16 changes: 8 additions & 8 deletions src/insn_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub trait IntoBytes {
}

/// General implementation of `IntoBytes` for `Instruction`
impl<'i, I: Instruction> IntoBytes for &'i I {
impl<I: Instruction> IntoBytes for &I {
type Bytes = Vec<u8>;

/// transform immutable reference of `Instruction` into `Vec<u8>` with size of 8
Expand Down Expand Up @@ -310,7 +310,7 @@ impl<'i> Move<'i> {
}
}

impl<'i> Instruction for Move<'i> {
impl Instruction for Move<'_> {
fn opt_code_byte(&self) -> u8 {
let op_bits = self.op_bits as u8;
let src_bit = self.src_bit as u8;
Expand Down Expand Up @@ -386,7 +386,7 @@ impl<'i> SwapBytes<'i> {
}
}

impl<'i> Instruction for SwapBytes<'i> {
impl Instruction for SwapBytes<'_> {
fn opt_code_byte(&self) -> u8 {
self.endian as u8
}
Expand Down Expand Up @@ -431,7 +431,7 @@ impl<'i> Load<'i> {
}
}

impl<'i> Instruction for Load<'i> {
impl Instruction for Load<'_> {
fn opt_code_byte(&self) -> u8 {
let size = self.mem_size as u8;
let addressing = self.addressing as u8;
Expand Down Expand Up @@ -464,7 +464,7 @@ impl<'i> Store<'i> {
}
}

impl<'i> Instruction for Store<'i> {
impl Instruction for Store<'_> {
fn opt_code_byte(&self) -> u8 {
let size = self.mem_size as u8;
BPF_MEM | BPF_ST | size | self.source
Expand Down Expand Up @@ -521,7 +521,7 @@ impl<'i> Jump<'i> {
}
}

impl<'i> Instruction for Jump<'i> {
impl Instruction for Jump<'_> {
fn opt_code_byte(&self) -> u8 {
let cmp: u8 = self.cond as u8;
let src_bit = self.src_bit as u8;
Expand Down Expand Up @@ -585,7 +585,7 @@ impl<'i> FunctionCall<'i> {
}
}

impl<'i> Instruction for FunctionCall<'i> {
impl Instruction for FunctionCall<'_> {
fn opt_code_byte(&self) -> u8 {
BPF_CALL | BPF_JMP
}
Expand Down Expand Up @@ -614,7 +614,7 @@ impl<'i> Exit<'i> {
}
}

impl<'i> Instruction for Exit<'i> {
impl Instruction for Exit<'_> {
fn opt_code_byte(&self) -> u8 {
BPF_EXIT | BPF_JMP
}
Expand Down
4 changes: 2 additions & 2 deletions src/memory_region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ pub struct UnalignedMemoryMapping<'a> {
cow_cb: Option<MemoryCowCallback>,
}

impl<'a> fmt::Debug for UnalignedMemoryMapping<'a> {
impl fmt::Debug for UnalignedMemoryMapping<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("UnalignedMemoryMapping")
.field("regions", &self.regions)
Expand Down Expand Up @@ -559,7 +559,7 @@ pub struct AlignedMemoryMapping<'a> {
cow_cb: Option<MemoryCowCallback>,
}

impl<'a> fmt::Debug for AlignedMemoryMapping<'a> {
impl fmt::Debug for AlignedMemoryMapping<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("AlignedMemoryMapping")
.field("regions", &self.regions)
Expand Down
Binary file removed tests/elfs/bss_section.so
Binary file not shown.
Binary file added tests/elfs/bss_section_sbpfv1.so
Binary file not shown.
Binary file not shown.
37 changes: 11 additions & 26 deletions tests/elfs/elfs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,35 @@ LD_COMMON="$TOOLCHAIN/llvm/bin/ld.lld -z notext -shared --Bdynamic -entry entryp
LD="$LD_COMMON --section-start=.text=0x100000000"
LD_V1=$LD_COMMON

$RC -o relative_call.o relative_call.rs
$LD -o relative_call.so relative_call.o
$RC_V1 -o relative_call.o relative_call.rs
$LD_V1 -o relative_call_sbpfv1.so relative_call.o

$RC_V1 -o syscall_reloc_64_32.o syscall_reloc_64_32.rs
$LD_V1 -o syscall_reloc_64_32.so syscall_reloc_64_32.o
$LD_V1 -o syscall_reloc_64_32_sbpfv1.so syscall_reloc_64_32.o

$RC -o syscall_static.o syscall_static.rs
$LD -o syscall_static.so syscall_static.o
$RC_V1 -o bss_section.o bss_section.rs
$LD_V1 -o bss_section_sbpfv1.so bss_section.o

$RC -o bss_section.o bss_section.rs
$LD -o bss_section.so bss_section.o

$RC -o data_section.o data_section.rs
$LD -o data_section.so data_section.o
$RC_V1 -o data_section.o data_section.rs
$LD_V1 -o data_section_sbpfv1.so data_section.o

$RC_V1 -o rodata_section.o rodata_section.rs
$LD_V1 -o rodata_section_sbpfv1.so rodata_section.o

$RC -o rodata_section.o rodata_section.rs
$LD -o rodata_section.so rodata_section.o

$RC -o program_headers_overflow.o rodata_section.rs
"$TOOLCHAIN"/llvm/bin/ld.lld -z notext -shared --Bdynamic -entry entrypoint --script program_headers_overflow.ld --noinhibit-exec -o program_headers_overflow.so program_headers_overflow.o

$RC -o struct_func_pointer.o struct_func_pointer.rs
$LD -o struct_func_pointer.so struct_func_pointer.o

$RC -o reloc_64_64.o reloc_64_64.rs
$LD -o reloc_64_64.so reloc_64_64.o
$RC_V1 -o struct_func_pointer.o struct_func_pointer.rs
$LD_V1 -o struct_func_pointer_sbpfv1.so struct_func_pointer.o

$RC_V1 -o reloc_64_64.o reloc_64_64.rs
$LD_V1 -o reloc_64_64_sbpfv1.so reloc_64_64.o

$RC -o reloc_64_relative.o reloc_64_relative.rs
$LD -o reloc_64_relative.so reloc_64_relative.o

$RC_V1 -o reloc_64_relative.o reloc_64_relative.rs
$LD_V1 -o reloc_64_relative_sbpfv1.so reloc_64_relative.o

# $RC -o reloc_64_relative_data.o reloc_64_relative_data.rs
# $LD -o reloc_64_relative_data.so reloc_64_relative_data.o#

# $RC_V1 -o reloc_64_relative_data.o reloc_64_relative_data.rs
# $LD_V1 -o reloc_64_relative_data_sbpfv1.so reloc_64_relative_data.o
$RC_V1 -o reloc_64_relative_data.o reloc_64_relative_data.rs
$LD_V1 -o reloc_64_relative_data_sbpfv1.so reloc_64_relative_data.o

# $RC_V1 -o callx_unaligned.o callx_unaligned.rs
# $LD_V1 -o callx_unaligned.so callx_unaligned.o
Expand Down
Binary file removed tests/elfs/relative_call.so
Binary file not shown.
Binary file renamed tests/elfs/syscall_static.so → tests/elfs/relative_call_sbpfv1.so
100755 → 100644
Binary file not shown.
Binary file removed tests/elfs/reloc_64_64.so
Binary file not shown.
Binary file removed tests/elfs/reloc_64_relative.so
Binary file not shown.
Binary file removed tests/elfs/reloc_64_relative_data.so
Binary file not shown.
Binary file removed tests/elfs/rodata_section.so
Binary file not shown.
Binary file not shown.
File renamed without changes.
Loading

0 comments on commit c06f051

Please sign in to comment.