1 // SPDX-License-Identifier: 0BSD 2 3 /////////////////////////////////////////////////////////////////////////////// 4 // 5 /// \file powerpc.c 6 /// \brief Filter for PowerPC (big endian) binaries 7 /// 8 // Authors: Igor Pavlov 9 // Lasse Collin 10 // 11 /////////////////////////////////////////////////////////////////////////////// 12 13 #include "simple_private.h" 14 15 16 static size_t 17 powerpc_code(void *simple lzma_attribute((__unused__)), 18 uint32_t now_pos, bool is_encoder, 19 uint8_t *buffer, size_t size) 20 { 21 size &= ~(size_t)3; 22 23 size_t i; 24 for (i = 0; i < size; i += 4) { 25 // PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link) 26 if ((buffer[i] >> 2) == 0x12 27 && ((buffer[i + 3] & 3) == 1)) { 28 29 const uint32_t src 30 = (((uint32_t)(buffer[i + 0]) & 3) << 24) 31 | ((uint32_t)(buffer[i + 1]) << 16) 32 | ((uint32_t)(buffer[i + 2]) << 8) 33 | ((uint32_t)(buffer[i + 3]) & ~UINT32_C(3)); 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 buffer[i + 0] = 0x48 | ((dest >> 24) & 0x03); 42 buffer[i + 1] = (dest >> 16); 43 buffer[i + 2] = (dest >> 8); 44 buffer[i + 3] &= 0x03; 45 buffer[i + 3] |= dest; 46 } 47 } 48 49 return i; 50 } 51 52 53 static lzma_ret 54 powerpc_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, 55 const lzma_filter_info *filters, bool is_encoder) 56 { 57 return lzma_simple_coder_init(next, allocator, filters, 58 &powerpc_code, 0, 4, 4, is_encoder); 59 } 60 61 62 #ifdef HAVE_ENCODER_POWERPC 63 extern lzma_ret 64 lzma_simple_powerpc_encoder_init(lzma_next_coder *next, 65 const lzma_allocator *allocator, 66 const lzma_filter_info *filters) 67 { 68 return powerpc_coder_init(next, allocator, filters, true); 69 } 70 #endif 71 72 73 #ifdef HAVE_DECODER_POWERPC 74 extern lzma_ret 75 lzma_simple_powerpc_decoder_init(lzma_next_coder *next, 76 const lzma_allocator *allocator, 77 const lzma_filter_info *filters) 78 { 79 return powerpc_coder_init(next, allocator, filters, false); 80 } 81 #endif 82