Home | History | Annotate | Line # | Download | only in simple
      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 &= ~(size_t)3;
     22 
     23 	size_t i;
     24 	for (i = 0; i < size; i += 4) {
     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 #ifdef HAVE_ENCODER_SPARC
     69 extern lzma_ret
     70 lzma_simple_sparc_encoder_init(lzma_next_coder *next,
     71 		const lzma_allocator *allocator,
     72 		const lzma_filter_info *filters)
     73 {
     74 	return sparc_coder_init(next, allocator, filters, true);
     75 }
     76 #endif
     77 
     78 
     79 #ifdef HAVE_DECODER_SPARC
     80 extern lzma_ret
     81 lzma_simple_sparc_decoder_init(lzma_next_coder *next,
     82 		const lzma_allocator *allocator,
     83 		const lzma_filter_info *filters)
     84 {
     85 	return sparc_coder_init(next, allocator, filters, false);
     86 }
     87 #endif
     88