diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-11-08 22:27:05 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-11-08 22:27:05 +0000 |
commit | 20f41f6819f77cbef698648b1ecc218244d974cc (patch) | |
tree | fec62091f9e9c643bc673279ac74e5abcad3173e | |
parent | 08632528aff54f3846c957ce0ccdffcb51ef9e5d (diff) | |
parent | 9c2600531b9ca77cda117e1cab77043649baa10d (diff) | |
download | apf-20f41f6819f77cbef698648b1ecc218244d974cc.tar.gz |
Snap for 11071797 from 9c2600531b9ca77cda117e1cab77043649baa10d to mainline-conscrypt-release
Change-Id: Id9d440f119aaca843f0313029df6f111081e0405
-rw-r--r-- | disassembler.c | 60 | ||||
-rw-r--r-- | v5/apf.h | 11 |
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, @@ -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) |