summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-08 22:27:05 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-08 22:27:05 +0000
commit20f41f6819f77cbef698648b1ecc218244d974cc (patch)
treefec62091f9e9c643bc673279ac74e5abcad3173e
parent08632528aff54f3846c957ce0ccdffcb51ef9e5d (diff)
parent9c2600531b9ca77cda117e1cab77043649baa10d (diff)
downloadapf-20f41f6819f77cbef698648b1ecc218244d974cc.tar.gz
Snap for 11071797 from 9c2600531b9ca77cda117e1cab77043649baa10d to mainline-conscrypt-release
Change-Id: Id9d440f119aaca843f0313029df6f111081e0405
-rw-r--r--disassembler.c60
-rw-r--r--v5/apf.h11
2 files changed, 65 insertions, 6 deletions
diff --git a/disassembler.c b/disassembler.c
index 6db8d7d..06a164b 100644
--- a/disassembler.c
+++ b/disassembler.c
@@ -113,6 +113,10 @@ uint32_t apf_disassemble(const uint8_t* program, uint32_t program_len,
const uint32_t opcode = EXTRACT_OPCODE(bytecode);
#define PRINT_OPCODE() \
print_opcode(opcode_names[opcode], output_buffer, output_buffer_len, offset)
+#define DECODE_IMM(value, length) \
+ for (uint32_t i = 0; i < (length) && pc < program_len; i++) \
+ value = (value << 8) | program[pc++]
+
const uint32_t reg_num = EXTRACT_REGISTER(bytecode);
// All instructions have immediate fields, so load them now.
const uint32_t len_field = EXTRACT_IMM_LENGTH(bytecode);
@@ -120,8 +124,7 @@ uint32_t apf_disassemble(const uint8_t* program, uint32_t program_len,
int32_t signed_imm = 0;
if (len_field != 0) {
const uint32_t imm_len = 1 << (len_field - 1);
- for (uint32_t i = 0; i < imm_len && pc < program_len; i++)
- imm = (imm << 8) | program[pc++];
+ DECODE_IMM(imm, imm_len);
// Sign extend imm into signed_imm.
signed_imm = imm << ((4 - imm_len) * 8);
signed_imm >>= (4 - imm_len) * 8;
@@ -193,10 +196,7 @@ uint32_t apf_disassemble(const uint8_t* program, uint32_t program_len,
ASSERT_RET_INBOUND(ret);
offset += ret;
} else {
- uint32_t cmp_imm_len = 1 << (len_field - 1);
- uint32_t i;
- for (i = 0; i < cmp_imm_len && pc < program_len; i++)
- cmp_imm = (cmp_imm << 8) | program[pc++];
+ DECODE_IMM(cmp_imm, 1 << (len_field - 1));
ret = snprintf(output_buffer + offset,
output_buffer_len - offset, "0x%x, ", cmp_imm);
ASSERT_RET_INBOUND(ret);
@@ -381,6 +381,32 @@ uint32_t apf_disassemble(const uint8_t* program, uint32_t program_len,
offset += ret;
break;
}
+ case EDATACOPY:
+ case EPKTCOPY: {
+ if (imm == EPKTCOPY) {
+ ret = print_opcode("pcopy", output_buffer,
+ output_buffer_len, offset);
+ } else {
+ ret = print_opcode("dcopy", output_buffer,
+ output_buffer_len, offset);
+ }
+ ASSERT_RET_INBOUND(ret);
+ offset += ret;
+ if (len_field > 0) {
+ const uint32_t imm_len = 1 << (len_field - 1);
+ uint32_t relative_offs = 0;
+ DECODE_IMM(relative_offs, imm_len);
+ uint32_t copy_len = 0;
+ DECODE_IMM(copy_len, 1);
+
+ ret = snprintf(
+ output_buffer + offset, output_buffer_len - offset,
+ "[r%u+%d], %d", reg_num, relative_offs, copy_len);
+ ASSERT_RET_INBOUND(ret);
+ offset += ret;
+ }
+ break;
+ }
default:
ret = snprintf(output_buffer + offset,
output_buffer_len - offset, "unknown_ext %u",
@@ -437,6 +463,28 @@ uint32_t apf_disassemble(const uint8_t* program, uint32_t program_len,
}
break;
}
+ case MEMCOPY_OPCODE: {
+ if (reg_num == 0) {
+ ret = print_opcode("pcopy", output_buffer, output_buffer_len,
+ offset);
+ } else {
+ ret = print_opcode("dcopy", output_buffer, output_buffer_len,
+ offset);
+ }
+ ASSERT_RET_INBOUND(ret);
+ offset += ret;
+ if (len_field > 0) {
+ uint32_t src_offs = imm;
+ uint32_t copy_len = 0;
+ DECODE_IMM(copy_len, 1);
+ ret =
+ snprintf(output_buffer + offset, output_buffer_len - offset,
+ "%d, %d", src_offs, copy_len);
+ ASSERT_RET_INBOUND(ret);
+ offset += ret;
+ }
+ break;
+ }
// Unknown opcode
default:
ret = snprintf(output_buffer + offset, output_buffer_len - offset,
diff --git a/v5/apf.h b/v5/apf.h
index e981593..a75ab1b 100644
--- a/v5/apf.h
+++ b/v5/apf.h
@@ -159,6 +159,11 @@
#define LDDW_OPCODE 22 // Load 4 bytes from data address (register + simm): "lddw R0, [5+R1]"
#define STDW_OPCODE 23 // Store 4 bytes to data address (register + simm): "stdw R0, [5+R1]"
#define WRITE_OPCODE 24 // Write 1, 2 or 4 bytes imm to the output buffer, e.g. "WRITE 5"
+// Copy the data from input packet or APF data region to output buffer. Register bit is
+// used to specify the source of data copy: R=0 means copy from packet, R=1 means copy
+// from APF data region. The source offset is encoded in the first imm and the copy length
+// is encoded in the second imm. "e.g. MEMCOPY(R=0), 5, 5"
+#define MEMCOPY_OPCODE 25
// Extended opcodes. These all have an opcode of EXT_OPCODE
// and specify the actual opcode in the immediate field.
@@ -175,6 +180,12 @@
#define EWRITE1_EXT_OPCODE 38 // Write 1 byte from register to the output buffer, e.g. "EWRITE1 R0"
#define EWRITE2_EXT_OPCODE 39 // Write 2 bytes from register to the output buffer, e.g. "EWRITE2 R0"
#define EWRITE4_EXT_OPCODE 40 // Write 4 bytes from register to the output buffer, e.g. "EWRITE4 R0"
+// Copy the data from input packet to output buffer. The source offset is encoded as [Rx + second imm].
+// The copy length is encoded in the third imm. "e.g. EPKTCOPY [R0 + 5], 5"
+#define EPKTCOPY 41
+// Copy the data from APF data region to output buffer. The source offset is encoded as [Rx + second imm].
+// The copy length is encoded in the third imm. "e.g. EDATACOPY [R0 + 5], 5"
+#define EDATACOPY 42
#define EXTRACT_OPCODE(i) (((i) >> 3) & 31)
#define EXTRACT_REGISTER(i) ((i) & 1)