1207753Smm///////////////////////////////////////////////////////////////////////////////
2207753Smm//
3207753Smm/// \file       arm.c
4207753Smm/// \brief      Filter for ARM binaries
5207753Smm///
6207753Smm//  Authors:    Igor Pavlov
7207753Smm//              Lasse Collin
8207753Smm//
9207753Smm//  This file has been put into the public domain.
10207753Smm//  You can do whatever you want with this file.
11207753Smm//
12207753Smm///////////////////////////////////////////////////////////////////////////////
13207753Smm
14207753Smm#include "simple_private.h"
15207753Smm
16207753Smm
17207753Smmstatic size_t
18223935Smmarm_code(lzma_simple *simple lzma_attribute((__unused__)),
19207753Smm		uint32_t now_pos, bool is_encoder,
20207753Smm		uint8_t *buffer, size_t size)
21207753Smm{
22207753Smm	size_t i;
23207753Smm	for (i = 0; i + 4 <= size; i += 4) {
24207753Smm		if (buffer[i + 3] == 0xEB) {
25207753Smm			uint32_t src = (buffer[i + 2] << 16)
26207753Smm					| (buffer[i + 1] << 8)
27207753Smm					| (buffer[i + 0]);
28207753Smm			src <<= 2;
29207753Smm
30207753Smm			uint32_t dest;
31207753Smm			if (is_encoder)
32207753Smm				dest = now_pos + (uint32_t)(i) + 8 + src;
33207753Smm			else
34207753Smm				dest = src - (now_pos + (uint32_t)(i) + 8);
35207753Smm
36207753Smm			dest >>= 2;
37207753Smm			buffer[i + 2] = (dest >> 16);
38207753Smm			buffer[i + 1] = (dest >> 8);
39207753Smm			buffer[i + 0] = dest;
40207753Smm		}
41207753Smm	}
42207753Smm
43207753Smm	return i;
44207753Smm}
45207753Smm
46207753Smm
47207753Smmstatic lzma_ret
48278433Srpauloarm_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
49207753Smm		const lzma_filter_info *filters, bool is_encoder)
50207753Smm{
51207753Smm	return lzma_simple_coder_init(next, allocator, filters,
52207753Smm			&arm_code, 0, 4, 4, is_encoder);
53207753Smm}
54207753Smm
55207753Smm
56207753Smmextern lzma_ret
57278433Srpaulolzma_simple_arm_encoder_init(lzma_next_coder *next,
58278433Srpaulo		const lzma_allocator *allocator,
59207753Smm		const lzma_filter_info *filters)
60207753Smm{
61207753Smm	return arm_coder_init(next, allocator, filters, true);
62207753Smm}
63207753Smm
64207753Smm
65207753Smmextern lzma_ret
66278433Srpaulolzma_simple_arm_decoder_init(lzma_next_coder *next,
67278433Srpaulo		const lzma_allocator *allocator,
68207753Smm		const lzma_filter_info *filters)
69207753Smm{
70207753Smm	return arm_coder_init(next, allocator, filters, false);
71207753Smm}
72