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 if (size < 4) 22 return 0; 23 24 size -= 4; 25 26 size_t i; 27 for (i = 0; i <= size; i += 2) { 28 if ((buffer[i + 1] & 0xF8) == 0xF0 29 && (buffer[i + 3] & 0xF8) == 0xF8) { 30 uint32_t src = (((uint32_t)(buffer[i + 1]) & 7) << 19) 31 | ((uint32_t)(buffer[i + 0]) << 11) 32 | (((uint32_t)(buffer[i + 3]) & 7) << 8) 33 | (uint32_t)(buffer[i + 2]); 34 35 src <<= 1; 36 37 uint32_t dest; 38 if (is_encoder) 39 dest = now_pos + (uint32_t)(i) + 4 + src; 40 else 41 dest = src - (now_pos + (uint32_t)(i) + 4); 42 43 dest >>= 1; 44 buffer[i + 1] = 0xF0 | ((dest >> 19) & 0x7); 45 buffer[i + 0] = (dest >> 11); 46 buffer[i + 3] = 0xF8 | ((dest >> 8) & 0x7); 47 buffer[i + 2] = (dest); 48 i += 2; 49 } 50 } 51 52 return i; 53 } 54 55 56 static lzma_ret 57 armthumb_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, 58 const lzma_filter_info *filters, bool is_encoder) 59 { 60 return lzma_simple_coder_init(next, allocator, filters, 61 &armthumb_code, 0, 4, 2, is_encoder); 62 } 63 64 65 #ifdef HAVE_ENCODER_ARMTHUMB 66 extern lzma_ret 67 lzma_simple_armthumb_encoder_init(lzma_next_coder *next, 68 const lzma_allocator *allocator, 69 const lzma_filter_info *filters) 70 { 71 return armthumb_coder_init(next, allocator, filters, true); 72 } 73 #endif 74 75 76 #ifdef HAVE_DECODER_ARMTHUMB 77 extern lzma_ret 78 lzma_simple_armthumb_decoder_init(lzma_next_coder *next, 79 const lzma_allocator *allocator, 80 const lzma_filter_info *filters) 81 { 82 return armthumb_coder_init(next, allocator, filters, false); 83 } 84 #endif 85