1 /////////////////////////////////////////////////////////////////////////////// 2 // 3 /// \file sparc.c 4 /// \brief Filter for SPARC binaries 5 /// 6 // Authors: Igor Pavlov 7 // Lasse Collin 8 // 9 // This file has been put into the public domain. 10 // You can do whatever you want with this file. 11 // 12 /////////////////////////////////////////////////////////////////////////////// 13 14 #include "simple_private.h" 15 16 17 static size_t 18 sparc_code(void *simple lzma_attribute((__unused__)), 19 uint32_t now_pos, bool is_encoder, 20 uint8_t *buffer, size_t size) 21 { 22 size_t i; 23 for (i = 0; i + 4 <= size; i += 4) { 24 25 if ((buffer[i] == 0x40 && (buffer[i + 1] & 0xC0) == 0x00) 26 || (buffer[i] == 0x7F 27 && (buffer[i + 1] & 0xC0) == 0xC0)) { 28 29 uint32_t src = ((uint32_t)buffer[i + 0] << 24) 30 | ((uint32_t)buffer[i + 1] << 16) 31 | ((uint32_t)buffer[i + 2] << 8) 32 | ((uint32_t)buffer[i + 3]); 33 34 src <<= 2; 35 36 uint32_t dest; 37 if (is_encoder) 38 dest = now_pos + (uint32_t)(i) + src; 39 else 40 dest = src - (now_pos + (uint32_t)(i)); 41 42 dest >>= 2; 43 44 dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) 45 | (dest & 0x3FFFFF) 46 | 0x40000000; 47 48 buffer[i + 0] = (uint8_t)(dest >> 24); 49 buffer[i + 1] = (uint8_t)(dest >> 16); 50 buffer[i + 2] = (uint8_t)(dest >> 8); 51 buffer[i + 3] = (uint8_t)(dest); 52 } 53 } 54 55 return i; 56 } 57 58 59 static lzma_ret 60 sparc_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, 61 const lzma_filter_info *filters, bool is_encoder) 62 { 63 return lzma_simple_coder_init(next, allocator, filters, 64 &sparc_code, 0, 4, 4, is_encoder); 65 } 66 67 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 76 77 extern lzma_ret 78 lzma_simple_sparc_decoder_init(lzma_next_coder *next, 79 const lzma_allocator *allocator, 80 const lzma_filter_info *filters) 81 { 82 return sparc_coder_init(next, allocator, filters, false); 83 } 84