Merge "Adjust APF interpreter tests to match APFv4" into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
580a1ed904
@@ -841,30 +841,30 @@ public class ApfGenerator {
|
||||
|
||||
/**
|
||||
* Add an instruction to the end of the program to load 32 bits from the data memory into
|
||||
* {@code register}. The source address is computed by adding @{code offset} to the other
|
||||
* register.
|
||||
* {@code register}. The source address is computed by adding the signed immediate
|
||||
* @{code offset} to the other register.
|
||||
* Requires APF v3 or greater.
|
||||
*/
|
||||
public ApfGenerator addLoadData(Register destinationRegister, int offset)
|
||||
throws IllegalInstructionException {
|
||||
requireApfVersion(3);
|
||||
Instruction instruction = new Instruction(Opcodes.LDDW, destinationRegister);
|
||||
instruction.setUnsignedImm(offset);
|
||||
instruction.setSignedImm(offset);
|
||||
addInstruction(instruction);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an instruction to the end of the program to store 32 bits from {@code register} into the
|
||||
* data memory. The destination address is computed by adding @{code offset} to the other
|
||||
* register.
|
||||
* data memory. The destination address is computed by adding the signed immediate
|
||||
* @{code offset} to the other register.
|
||||
* Requires APF v3 or greater.
|
||||
*/
|
||||
public ApfGenerator addStoreData(Register sourceRegister, int offset)
|
||||
throws IllegalInstructionException {
|
||||
requireApfVersion(3);
|
||||
Instruction instruction = new Instruction(Opcodes.STDW, sourceRegister);
|
||||
instruction.setUnsignedImm(offset);
|
||||
instruction.setSignedImm(offset);
|
||||
addInstruction(instruction);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ public class ApfTest {
|
||||
throw new Exception(
|
||||
"program: " + HexDump.toHexString(program) +
|
||||
"\ndata memory: " + HexDump.toHexString(data) +
|
||||
"\nexpected: " + HexDump.toHexString(expected_data));
|
||||
"\nexpected: " + HexDump.toHexString(expected_data));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -625,18 +625,19 @@ public class ApfTest {
|
||||
@Test
|
||||
public void testApfDataWrite() throws IllegalInstructionException, Exception {
|
||||
byte[] packet = new byte[MIN_PKT_SIZE];
|
||||
byte[] data = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
|
||||
byte[] data = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
|
||||
byte[] expected_data = data.clone();
|
||||
|
||||
// No memory access instructions: should leave the data segment untouched.
|
||||
ApfGenerator gen = new ApfGenerator(3);
|
||||
assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
|
||||
|
||||
// Expect value 0x87654321 to be stored starting from address 3 + 2, in big-endian order.
|
||||
// Expect value 0x87654321 to be stored starting from address -11 from the end of the
|
||||
// data buffer, in big-endian order.
|
||||
gen = new ApfGenerator(3);
|
||||
gen.addLoadImmediate(Register.R0, 0x87654321);
|
||||
gen.addLoadImmediate(Register.R1, 2);
|
||||
gen.addStoreData(Register.R0, 3);
|
||||
gen.addLoadImmediate(Register.R1, -5);
|
||||
gen.addStoreData(Register.R0, -6); // -5 + -6 = -11 (offset +5 with data_len=16)
|
||||
expected_data[5] = (byte)0x87;
|
||||
expected_data[6] = (byte)0x65;
|
||||
expected_data[7] = (byte)0x43;
|
||||
@@ -646,16 +647,16 @@ public class ApfTest {
|
||||
|
||||
@Test
|
||||
public void testApfDataRead() throws IllegalInstructionException, Exception {
|
||||
// Program that DROPs if address 11 (7 + 3) contains 0x87654321.
|
||||
// Program that DROPs if address 10 (-6) contains 0x87654321.
|
||||
ApfGenerator gen = new ApfGenerator(3);
|
||||
gen.addLoadImmediate(Register.R1, 3);
|
||||
gen.addLoadData(Register.R0, 7);
|
||||
gen.addLoadImmediate(Register.R1, 10);
|
||||
gen.addLoadData(Register.R0, -16); // 10 + -16 = -6 (offset +10 with data_len=16)
|
||||
gen.addJumpIfR0Equals(0x87654321, gen.DROP_LABEL);
|
||||
byte[] program = gen.generate();
|
||||
byte[] packet = new byte[MIN_PKT_SIZE];
|
||||
|
||||
// Content is incorrect (last byte does not match) -> PASS
|
||||
byte[] data = new byte[32];
|
||||
byte[] data = new byte[16];
|
||||
data[10] = (byte)0x87;
|
||||
data[11] = (byte)0x65;
|
||||
data[12] = (byte)0x43;
|
||||
@@ -672,10 +673,10 @@ public class ApfTest {
|
||||
@Test
|
||||
public void testApfDataReadModifyWrite() throws IllegalInstructionException, Exception {
|
||||
ApfGenerator gen = new ApfGenerator(3);
|
||||
gen.addLoadImmediate(Register.R1, 3);
|
||||
gen.addLoadData(Register.R0, 7); // Load from address 7 + 3 = 10
|
||||
gen.addLoadImmediate(Register.R1, -22);
|
||||
gen.addLoadData(Register.R0, 0); // Load from address 32 -22 + 0 = 10
|
||||
gen.addAdd(0x78453412); // 87654321 + 78453412 = FFAA7733
|
||||
gen.addStoreData(Register.R0, 11); // Write back to address 11 + 3 = 14
|
||||
gen.addStoreData(Register.R0, 4); // Write back to address 32 -22 + 4 = 14
|
||||
|
||||
byte[] packet = new byte[MIN_PKT_SIZE];
|
||||
byte[] data = new byte[32];
|
||||
@@ -718,10 +719,17 @@ public class ApfTest {
|
||||
gen.addJump(gen.DROP_LABEL);
|
||||
assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
|
||||
|
||||
// ...but underflowing isn't allowed.
|
||||
// ...and underflowing simply wraps around to the end of the buffer...
|
||||
gen = new ApfGenerator(3);
|
||||
gen.addLoadImmediate(Register.R0, 20);
|
||||
gen.addLoadData(Register.R1, -30);
|
||||
gen.addJump(gen.DROP_LABEL);
|
||||
assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
|
||||
|
||||
// ...but doesn't allow accesses before the start of the buffer
|
||||
gen = new ApfGenerator(3);
|
||||
gen.addLoadImmediate(Register.R0, 20);
|
||||
gen.addLoadData(Register.R1, -1000);
|
||||
gen.addJump(gen.DROP_LABEL); // Not reached.
|
||||
assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
|
||||
}
|
||||
|
||||
@@ -36,11 +36,20 @@ static jint com_android_server_ApfTest_apfSimulate(
|
||||
uint32_t program_len = env->GetArrayLength(program);
|
||||
uint32_t packet_len = env->GetArrayLength(packet);
|
||||
uint32_t data_len = data ? env->GetArrayLength(data) : 0;
|
||||
jint result = accept_packet(program_raw, program_len, packet_raw,
|
||||
packet_len, data_raw, data_len, filter_age);
|
||||
|
||||
// Merge program and data into a single buffer.
|
||||
uint8_t* program_and_data = (uint8_t*)malloc(program_len + data_len);
|
||||
memcpy(program_and_data, program_raw, program_len);
|
||||
memcpy(program_and_data + program_len, data_raw, data_len);
|
||||
|
||||
jint result =
|
||||
accept_packet(program_and_data, program_len, program_len + data_len,
|
||||
packet_raw, packet_len, filter_age);
|
||||
if (data) {
|
||||
memcpy(data_raw, program_and_data + program_len, data_len);
|
||||
env->ReleaseByteArrayElements(data, (jbyte*)data_raw, 0 /* copy back */);
|
||||
}
|
||||
free(program_and_data);
|
||||
env->ReleaseByteArrayElements(packet, (jbyte*)packet_raw, JNI_ABORT);
|
||||
env->ReleaseByteArrayElements(program, (jbyte*)program_raw, JNI_ABORT);
|
||||
return result;
|
||||
@@ -109,8 +118,8 @@ static jboolean com_android_server_ApfTest_compareBpfApf(JNIEnv* env, jclass, js
|
||||
jstring jpcap_filename, jbyteArray japf_program) {
|
||||
ScopedUtfChars filter(env, jfilter);
|
||||
ScopedUtfChars pcap_filename(env, jpcap_filename);
|
||||
const uint8_t* apf_program = (uint8_t*)env->GetByteArrayElements(japf_program, NULL);
|
||||
const uint32_t apf_program_len = env->GetArrayLength(japf_program);
|
||||
uint8_t* apf_program = (uint8_t*)env->GetByteArrayElements(japf_program, NULL);
|
||||
uint32_t apf_program_len = env->GetArrayLength(japf_program);
|
||||
|
||||
// Open pcap file for BPF filtering
|
||||
ScopedFILE bpf_fp(fopen(pcap_filename.c_str(), "rb"));
|
||||
@@ -152,8 +161,8 @@ static jboolean com_android_server_ApfTest_compareBpfApf(JNIEnv* env, jclass, js
|
||||
do {
|
||||
apf_packet = pcap_next(apf_pcap.get(), &apf_header);
|
||||
} while (apf_packet != NULL && !accept_packet(
|
||||
apf_program, apf_program_len, apf_packet, apf_header.len,
|
||||
nullptr, 0, 0));
|
||||
apf_program, apf_program_len, 0 /* data_len */,
|
||||
apf_packet, apf_header.len, 0 /* filter_age */));
|
||||
|
||||
// Make sure both filters matched the same packet.
|
||||
if (apf_packet == NULL && bpf_packet == NULL)
|
||||
|
||||
Reference in New Issue
Block a user