1 // SPDX-License-Identifier: 0BSD 2 3 /////////////////////////////////////////////////////////////////////////////// 4 // 5 /// \file sparc.c 6 /// \brief Filter for SPARC binaries 7 /// 8 // Authors: Igor Pavlov 9 // Lasse Collin 10 // 11 /////////////////////////////////////////////////////////////////////////////// 12 13 #include "simple_private.h" 14 15 16 static size_t 17 sparc_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 += 4) { 23 24 if ((buffer[i] == 0x40 && (buffer[i + 1] & 0xC0) == 0x00) 25 || (buffer[i] == 0x7F 26 && (buffer[i + 1] & 0xC0) == 0xC0)) { 27 28 uint32_t src = ((uint32_t)buffer[i + 0] << 24) 29 | ((uint32_t)buffer[i + 1] << 16) 30 | ((uint32_t)buffer[i + 2] << 8) 31 | ((uint32_t)buffer[i + 3]); 32 33 src <<= 2; 34 35 uint32_t dest; 36 if (is_encoder) 37 dest = now_pos + (uint32_t)(i) + src; 38 else 39 dest = src - (now_pos + (uint32_t)(i)); 40 41 dest >>= 2; 42 43 dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) 44 | (dest & 0x3FFFFF) 45 | 0x40000000; 46 47 buffer[i + 0] = (uint8_t)(dest >> 24); 48 buffer[i + 1] = (uint8_t)(dest >> 16); 49 buffer[i + 2] = (uint8_t)(dest >> 8); 50 buffer[i + 3] = (uint8_t)(dest); 51 } 52 } 53 54 return i; 55 } 56 57 58 static lzma_ret 59 sparc_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, 60 const lzma_filter_info *filters, bool is_encoder) 61 { 62 return lzma_simple_coder_init(next, allocator, filters, 63 &sparc_code, 0, 4, 4, is_encoder); 64 } 65 66 67 #ifdef HAVE_ENCODER_SPARC 68 extern lzma_ret 69 lzma_simple_sparc_encoder_init(lzma_next_coder *next, 70 const lzma_allocator *allocator, 71 const lzma_filter_info *filters) 72 { 73 return sparc_coder_init(next, allocator, filters, true); 74 } 75 #endif 76 77 78 #ifdef HAVE_DECODER_SPARC 79 extern lzma_ret 80 lzma_simple_sparc_decoder_init(lzma_next_coder *next, 81 const lzma_allocator *allocator, 82 const lzma_filter_info *filters) 83 { 84 return sparc_coder_init(next, allocator, filters, false); 85 } 86 #endif 87