@@ -16,12 +16,18 @@ LOG_MODULE_REGISTER(nrf_compress_arm_thumb, CONFIG_NRF_COMPRESS_LOG_LEVEL);
1616BUILD_ASSERT ((CONFIG_NRF_COMPRESS_CHUNK_SIZE % 4 ) == 0 ,
1717 "CONFIG_NRF_COMPRESS_CHUNK_SIZE must be multiple of 4" );
1818
19- static uint8_t output_buffer [CONFIG_NRF_COMPRESS_CHUNK_SIZE ];
19+ /* Requires 2 extra bytes to allow checking cross-chunk 16-bit aligned ARM thumb instructions */
20+ #define EXTRA_BUFFER_SIZE 2
21+
22+ static uint8_t output_buffer [CONFIG_NRF_COMPRESS_CHUNK_SIZE + EXTRA_BUFFER_SIZE ];
23+ static uint8_t temp_extra_buffer [EXTRA_BUFFER_SIZE ];
2024static uint32_t data_position = 0 ;
25+ static bool has_extra_buffer_data ;
2126
2227static int arm_thumb_init (void * inst )
2328{
2429 data_position = 0 ;
30+ has_extra_buffer_data = false;
2531
2632 return 0 ;
2733}
@@ -38,6 +44,7 @@ static int arm_thumb_deinit(void *inst)
3844static int arm_thumb_reset (void * inst )
3945{
4046 data_position = 0 ;
47+ has_extra_buffer_data = false;
4148 memset (output_buffer , 0x00 , sizeof (output_buffer ));
4249
4350 return 0 ;
@@ -52,17 +59,47 @@ static int arm_thumb_decompress(void *inst, const uint8_t *input, size_t input_s
5259 bool last_part , uint32_t * offset , uint8_t * * output ,
5360 size_t * output_size )
5461{
62+ bool end_part_match = false;
63+ bool extra_buffer_used = false;
64+
5565 if (input_size > CONFIG_NRF_COMPRESS_CHUNK_SIZE ) {
5666 return - EINVAL ;
5767 }
5868
59- memcpy (output_buffer , input , input_size );
60- arm_thumb_filter (output_buffer , input_size , data_position , false);
69+ if (has_extra_buffer_data == true) {
70+ /* Copy bytes from temporary holding buffer */
71+ memcpy (output_buffer , temp_extra_buffer , sizeof (temp_extra_buffer ));
72+ memcpy (& output_buffer [sizeof (temp_extra_buffer )], input , input_size );
73+ end_part_match = true;
74+ extra_buffer_used = true;
75+ has_extra_buffer_data = false;
76+ input_size += sizeof (temp_extra_buffer );
77+ } else {
78+ memcpy (output_buffer , input , input_size );
79+ }
80+
81+ arm_thumb_filter (output_buffer , input_size , data_position , false, & end_part_match );
6182 data_position += input_size ;
6283 * offset = input_size ;
84+
85+ if (extra_buffer_used ) {
86+ * offset -= sizeof (temp_extra_buffer );
87+ }
88+
6389 * output = output_buffer ;
6490 * output_size = input_size ;
6591
92+ if (end_part_match == true && !last_part ) {
93+ /* Partial match at end of input, need to cut the final 2 bytes off and stash
94+ * them
95+ */
96+ memcpy (temp_extra_buffer , & output_buffer [(input_size - sizeof (temp_extra_buffer ))],
97+ sizeof (temp_extra_buffer ));
98+ has_extra_buffer_data = true;
99+ * output_size -= sizeof (temp_extra_buffer );
100+ data_position -= sizeof (temp_extra_buffer );
101+ }
102+
66103 return 0 ;
67104}
68105
0 commit comments