1 // SPDX-License-Identifier: 0BSD 2 3 /////////////////////////////////////////////////////////////////////////////// 4 // 5 /// \file armthumb.c 6 /// \brief Filter for ARM-Thumb binaries 7 /// 8 // Authors: Igor Pavlov 9 // Lasse Collin 10 // 11 /////////////////////////////////////////////////////////////////////////////// 12 13 #include "simple_private.h" 14 15 16 static size_t 17 armthumb_code(void *simple lzma_attribute((__unused__)), 18 uint32_t now_pos, bool is_encoder, 19 uint8_t *buffer, size_t size) 20 { 21 size_t i; 22 for (i = 0; i + 4 <= size; i += 2) { 23 if ((buffer[i + 1] & 0xF8) == 0xF0 24 && (buffer[i + 3] & 0xF8) == 0xF8) { 25 uint32_t src = (((uint32_t)(buffer[i + 1]) & 7) << 19) 26 | ((uint32_t)(buffer[i + 0]) << 11) 27 | (((uint32_t)(buffer[i + 3]) & 7) << 8) 28 | (uint32_t)(buffer[i + 2]); 29 30 src <<= 1; 31 32 uint32_t dest; 33 if (is_encoder) 34 dest = now_pos + (uint32_t)(i) + 4 + src; 35 else 36 dest = src - (now_pos + (uint32_t)(i) + 4); 37 38 dest >>= 1; 39 buffer[i + 1] = 0xF0 | ((dest >> 19) & 0x7); 40 buffer[i + 0] = (dest >> 11); 41 buffer[i + 3] = 0xF8 | ((dest >> 8) & 0x7); 42 buffer[i + 2] = (dest); 43 i += 2; 44 } 45 } 46 47 return i; 48 } 49 50 51 static lzma_ret 52 armthumb_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, 53 const lzma_filter_info *filters, bool is_encoder) 54 { 55 return lzma_simple_coder_init(next, allocator, filters, 56 &armthumb_code, 0, 4, 2, is_encoder); 57 } 58 59 60 #ifdef HAVE_ENCODER_ARMTHUMB 61 extern lzma_ret 62 lzma_simple_armthumb_encoder_init(lzma_next_coder *next, 63 const lzma_allocator *allocator, 64 const lzma_filter_info *filters) 65 { 66 return armthumb_coder_init(next, allocator, filters, true); 67 } 68 #endif 69 70 71 #ifdef HAVE_DECODER_ARMTHUMB 72 extern lzma_ret 73 lzma_simple_armthumb_decoder_init(lzma_next_coder *next, 74 const lzma_allocator *allocator, 75 const lzma_filter_info *filters) 76 { 77 return armthumb_coder_init(next, allocator, filters, false); 78 } 79 #endif 80