1*3b35e7eeSXin LI // SPDX-License-Identifier: 0BSD 2*3b35e7eeSXin LI 381ad8388SMartin Matuska /////////////////////////////////////////////////////////////////////////////// 481ad8388SMartin Matuska // 581ad8388SMartin Matuska /// \file powerpc.c 681ad8388SMartin Matuska /// \brief Filter for PowerPC (big endian) binaries 781ad8388SMartin Matuska /// 881ad8388SMartin Matuska // Authors: Igor Pavlov 981ad8388SMartin Matuska // Lasse Collin 1081ad8388SMartin Matuska // 1181ad8388SMartin Matuska /////////////////////////////////////////////////////////////////////////////// 1281ad8388SMartin Matuska 1381ad8388SMartin Matuska #include "simple_private.h" 1481ad8388SMartin Matuska 1581ad8388SMartin Matuska 1681ad8388SMartin Matuska static size_t 171456f0f9SXin LI powerpc_code(void *simple lzma_attribute((__unused__)), 1881ad8388SMartin Matuska uint32_t now_pos, bool is_encoder, 1981ad8388SMartin Matuska uint8_t *buffer, size_t size) 2081ad8388SMartin Matuska { 2181ad8388SMartin Matuska size_t i; 2281ad8388SMartin Matuska for (i = 0; i + 4 <= size; i += 4) { 2381ad8388SMartin Matuska // PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link) 2481ad8388SMartin Matuska if ((buffer[i] >> 2) == 0x12 2581ad8388SMartin Matuska && ((buffer[i + 3] & 3) == 1)) { 2681ad8388SMartin Matuska 27a8675d92SXin LI const uint32_t src 28a8675d92SXin LI = (((uint32_t)(buffer[i + 0]) & 3) << 24) 29a8675d92SXin LI | ((uint32_t)(buffer[i + 1]) << 16) 30a8675d92SXin LI | ((uint32_t)(buffer[i + 2]) << 8) 31a8675d92SXin LI | ((uint32_t)(buffer[i + 3]) & ~UINT32_C(3)); 3281ad8388SMartin Matuska 3381ad8388SMartin Matuska uint32_t dest; 3481ad8388SMartin Matuska if (is_encoder) 3581ad8388SMartin Matuska dest = now_pos + (uint32_t)(i) + src; 3681ad8388SMartin Matuska else 3781ad8388SMartin Matuska dest = src - (now_pos + (uint32_t)(i)); 3881ad8388SMartin Matuska 3981ad8388SMartin Matuska buffer[i + 0] = 0x48 | ((dest >> 24) & 0x03); 4081ad8388SMartin Matuska buffer[i + 1] = (dest >> 16); 4181ad8388SMartin Matuska buffer[i + 2] = (dest >> 8); 4281ad8388SMartin Matuska buffer[i + 3] &= 0x03; 4381ad8388SMartin Matuska buffer[i + 3] |= dest; 4481ad8388SMartin Matuska } 4581ad8388SMartin Matuska } 4681ad8388SMartin Matuska 4781ad8388SMartin Matuska return i; 4881ad8388SMartin Matuska } 4981ad8388SMartin Matuska 5081ad8388SMartin Matuska 5181ad8388SMartin Matuska static lzma_ret 5253200025SRui Paulo powerpc_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, 5381ad8388SMartin Matuska const lzma_filter_info *filters, bool is_encoder) 5481ad8388SMartin Matuska { 5581ad8388SMartin Matuska return lzma_simple_coder_init(next, allocator, filters, 5681ad8388SMartin Matuska &powerpc_code, 0, 4, 4, is_encoder); 5781ad8388SMartin Matuska } 5881ad8388SMartin Matuska 5981ad8388SMartin Matuska 6073ed8e77SXin LI #ifdef HAVE_ENCODER_POWERPC 6181ad8388SMartin Matuska extern lzma_ret 6281ad8388SMartin Matuska lzma_simple_powerpc_encoder_init(lzma_next_coder *next, 6353200025SRui Paulo const lzma_allocator *allocator, 6453200025SRui Paulo const lzma_filter_info *filters) 6581ad8388SMartin Matuska { 6681ad8388SMartin Matuska return powerpc_coder_init(next, allocator, filters, true); 6781ad8388SMartin Matuska } 6873ed8e77SXin LI #endif 6981ad8388SMartin Matuska 7081ad8388SMartin Matuska 7173ed8e77SXin LI #ifdef HAVE_DECODER_POWERPC 7281ad8388SMartin Matuska extern lzma_ret 7381ad8388SMartin Matuska lzma_simple_powerpc_decoder_init(lzma_next_coder *next, 7453200025SRui Paulo const lzma_allocator *allocator, 7553200025SRui Paulo const lzma_filter_info *filters) 7681ad8388SMartin Matuska { 7781ad8388SMartin Matuska return powerpc_coder_init(next, allocator, filters, false); 7881ad8388SMartin Matuska } 7973ed8e77SXin LI #endif 80