1178172Simp// SPDX-License-Identifier: 0BSD 2178172Simp 3178172Simp/////////////////////////////////////////////////////////////////////////////// 4178172Simp// 5178172Simp/// \file powerpc.c 6178172Simp/// \brief Filter for PowerPC (big endian) binaries 7178172Simp/// 8178172Simp// Authors: Igor Pavlov 9178172Simp// Lasse Collin 10178172Simp// 11178172Simp/////////////////////////////////////////////////////////////////////////////// 12178172Simp 13178172Simp#include "simple_private.h" 14178172Simp 15178172Simp 16178172Simpstatic size_t 17178172Simppowerpc_code(void *simple lzma_attribute((__unused__)), 18178172Simp uint32_t now_pos, bool is_encoder, 19178172Simp uint8_t *buffer, size_t size) 20178172Simp{ 21178172Simp size_t i; 22178172Simp for (i = 0; i + 4 <= size; i += 4) { 23178172Simp // PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link) 24178172Simp if ((buffer[i] >> 2) == 0x12 25178172Simp && ((buffer[i + 3] & 3) == 1)) { 26178172Simp 27178172Simp const uint32_t src 28178172Simp = (((uint32_t)(buffer[i + 0]) & 3) << 24) 29178172Simp | ((uint32_t)(buffer[i + 1]) << 16) 30178172Simp | ((uint32_t)(buffer[i + 2]) << 8) 31178172Simp | ((uint32_t)(buffer[i + 3]) & ~UINT32_C(3)); 32178172Simp 33178172Simp uint32_t dest; 34178172Simp if (is_encoder) 35178172Simp dest = now_pos + (uint32_t)(i) + src; 36178172Simp else 37178172Simp dest = src - (now_pos + (uint32_t)(i)); 38178172Simp 39178172Simp buffer[i + 0] = 0x48 | ((dest >> 24) & 0x03); 40178172Simp buffer[i + 1] = (dest >> 16); 41178172Simp buffer[i + 2] = (dest >> 8); 42178172Simp buffer[i + 3] &= 0x03; 43178172Simp buffer[i + 3] |= dest; 44178172Simp } 45178172Simp } 46178172Simp 47178172Simp return i; 48178172Simp} 49178172Simp 50178172Simp 51178172Simpstatic lzma_ret 52178172Simppowerpc_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, 53178172Simp const lzma_filter_info *filters, bool is_encoder) 54178172Simp{ 55178172Simp return lzma_simple_coder_init(next, allocator, filters, 56178172Simp &powerpc_code, 0, 4, 4, is_encoder); 57178172Simp} 58178172Simp 59178172Simp 60178172Simp#ifdef HAVE_ENCODER_POWERPC 61178172Simpextern lzma_ret 62178172Simplzma_simple_powerpc_encoder_init(lzma_next_coder *next, 63178172Simp const lzma_allocator *allocator, 64178172Simp const lzma_filter_info *filters) 65178172Simp{ 66178172Simp return powerpc_coder_init(next, allocator, filters, true); 67178172Simp} 68178172Simp#endif 69178172Simp 70178172Simp 71178172Simp#ifdef HAVE_DECODER_POWERPC 72178172Simpextern lzma_ret 73178172Simplzma_simple_powerpc_decoder_init(lzma_next_coder *next, 74178172Simp const lzma_allocator *allocator, 75178172Simp const lzma_filter_info *filters) 76178172Simp{ 77178172Simp return powerpc_coder_init(next, allocator, filters, false); 78178172Simp} 79178172Simp#endif 80178172Simp