summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Bernie Innocenti <codewiz@google.com> 2018-04-19 07:25:11 -0700
committer android-build-merger <android-build-merger@google.com> 2018-04-19 07:25:11 -0700
commite56afce9e95b27a9ee53b4fa6938cb3421e600e8 (patch)
treed98588b50a5d74026000f26d610e25fa0a73ef7e
parent5124d28e64c6da5f807de136a70b2f168e885022 (diff)
parent05011abf27f1d16ea813952318d56cd2e7cc462e (diff)
Merge "Adjust APF interpreter tests to match APFv4"
am: 05011abf27 Change-Id: I5ca2b41ab6c101bef7465229270079c81743c757
-rw-r--r--services/net/java/android/net/apf/ApfGenerator.java12
-rw-r--r--tests/net/java/android/net/apf/ApfTest.java34
-rw-r--r--tests/net/jni/apf_jni.cpp21
3 files changed, 42 insertions, 25 deletions
diff --git a/services/net/java/android/net/apf/ApfGenerator.java b/services/net/java/android/net/apf/ApfGenerator.java
index fcfb19ce5a68..99b2fc6db472 100644
--- a/services/net/java/android/net/apf/ApfGenerator.java
+++ b/services/net/java/android/net/apf/ApfGenerator.java
@@ -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;
}
diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java
index 082f3108ed0a..f8a413226bd2 100644
--- a/tests/net/java/android/net/apf/ApfTest.java
+++ b/tests/net/java/android/net/apf/ApfTest.java
@@ -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);
}
diff --git a/tests/net/jni/apf_jni.cpp b/tests/net/jni/apf_jni.cpp
index 79444e3f5ba8..1ea9e274ab9e 100644
--- a/tests/net/jni/apf_jni.cpp
+++ b/tests/net/jni/apf_jni.cpp
@@ -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)