/src/xz/src/liblzma/simple/armthumb.c
Line | Count | Source |
1 | | // SPDX-License-Identifier: 0BSD |
2 | | |
3 | | /////////////////////////////////////////////////////////////////////////////// |
4 | | // |
5 | | /// \file armthumb.c |
6 | | /// \brief Filter for ARM-Thumb binaries |
7 | | /// |
8 | | // Authors: Igor Pavlov |
9 | | // Lasse Collin |
10 | | // |
11 | | /////////////////////////////////////////////////////////////////////////////// |
12 | | |
13 | | #include "simple_private.h" |
14 | | |
15 | | |
16 | | static size_t |
17 | | armthumb_code(void *simple lzma_attribute((__unused__)), |
18 | | uint32_t now_pos, bool is_encoder, |
19 | | uint8_t *buffer, size_t size) |
20 | 0 | { |
21 | 0 | if (size < 4) |
22 | 0 | return 0; |
23 | | |
24 | 0 | size -= 4; |
25 | |
|
26 | 0 | size_t i; |
27 | 0 | for (i = 0; i <= size; i += 2) { |
28 | 0 | if ((buffer[i + 1] & 0xF8) == 0xF0 |
29 | 0 | && (buffer[i + 3] & 0xF8) == 0xF8) { |
30 | 0 | uint32_t src = (((uint32_t)(buffer[i + 1]) & 7) << 19) |
31 | 0 | | ((uint32_t)(buffer[i + 0]) << 11) |
32 | 0 | | (((uint32_t)(buffer[i + 3]) & 7) << 8) |
33 | 0 | | (uint32_t)(buffer[i + 2]); |
34 | |
|
35 | 0 | src <<= 1; |
36 | |
|
37 | 0 | uint32_t dest; |
38 | 0 | if (is_encoder) |
39 | 0 | dest = now_pos + (uint32_t)(i) + 4 + src; |
40 | 0 | else |
41 | 0 | dest = src - (now_pos + (uint32_t)(i) + 4); |
42 | |
|
43 | 0 | dest >>= 1; |
44 | 0 | buffer[i + 1] = 0xF0 | ((dest >> 19) & 0x7); |
45 | 0 | buffer[i + 0] = (dest >> 11); |
46 | 0 | buffer[i + 3] = 0xF8 | ((dest >> 8) & 0x7); |
47 | 0 | buffer[i + 2] = (dest); |
48 | 0 | i += 2; |
49 | 0 | } |
50 | 0 | } |
51 | |
|
52 | 0 | return i; |
53 | 0 | } |
54 | | |
55 | | |
56 | | static lzma_ret |
57 | | armthumb_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, |
58 | | const lzma_filter_info *filters, bool is_encoder) |
59 | 0 | { |
60 | 0 | return lzma_simple_coder_init(next, allocator, filters, |
61 | 0 | &armthumb_code, 0, 4, 2, is_encoder); |
62 | 0 | } |
63 | | |
64 | | |
65 | | #ifdef HAVE_ENCODER_ARMTHUMB |
66 | | extern lzma_ret |
67 | | lzma_simple_armthumb_encoder_init(lzma_next_coder *next, |
68 | | const lzma_allocator *allocator, |
69 | | const lzma_filter_info *filters) |
70 | 0 | { |
71 | 0 | return armthumb_coder_init(next, allocator, filters, true); |
72 | 0 | } |
73 | | #endif |
74 | | |
75 | | |
76 | | #ifdef HAVE_DECODER_ARMTHUMB |
77 | | extern lzma_ret |
78 | | lzma_simple_armthumb_decoder_init(lzma_next_coder *next, |
79 | | const lzma_allocator *allocator, |
80 | | const lzma_filter_info *filters) |
81 | 0 | { |
82 | | return armthumb_coder_init(next, allocator, filters, false); |
83 | 0 | } |
84 | | #endif |