1 /////////////////////////////////////////////////////////////////////////////// 2 // 3 /// \file ia64.c 4 /// \brief Filter for IA64 (Itanium) binaries 5 /// 6 // Authors: Igor Pavlov 7 // Lasse Collin 8 // 9 // This file has been put into the public domain. 10 // You can do whatever you want with this file. 11 // 12 /////////////////////////////////////////////////////////////////////////////// 13 14 #include "simple_private.h" 15 16 17 static size_t 18 ia64_code(void *simple lzma_attribute((__unused__)), 19 uint32_t now_pos, bool is_encoder, 20 uint8_t *buffer, size_t size) 21 { 22 static const uint32_t BRANCH_TABLE[32] = { 23 0, 0, 0, 0, 0, 0, 0, 0, 24 0, 0, 0, 0, 0, 0, 0, 0, 25 4, 4, 6, 6, 0, 0, 7, 7, 26 4, 4, 0, 0, 4, 4, 0, 0 27 }; 28 29 size_t i; 30 for (i = 0; i + 16 <= size; i += 16) { 31 const uint32_t instr_template = buffer[i] & 0x1F; 32 const uint32_t mask = BRANCH_TABLE[instr_template]; 33 uint32_t bit_pos = 5; 34 35 for (size_t slot = 0; slot < 3; ++slot, bit_pos += 41) { 36 if (((mask >> slot) & 1) == 0) 37 continue; 38 39 const size_t byte_pos = (bit_pos >> 3); 40 const uint32_t bit_res = bit_pos & 0x7; 41 uint64_t instruction = 0; 42 43 for (size_t j = 0; j < 6; ++j) 44 instruction += (uint64_t)( 45 buffer[i + j + byte_pos]) 46 << (8 * j); 47 48 uint64_t inst_norm = instruction >> bit_res; 49 50 if (((inst_norm >> 37) & 0xF) == 0x5 51 && ((inst_norm >> 9) & 0x7) == 0 52 /* && (inst_norm & 0x3F)== 0 */ 53 ) { 54 uint32_t src = (uint32_t)( 55 (inst_norm >> 13) & 0xFFFFF); 56 src |= ((inst_norm >> 36) & 1) << 20; 57 58 src <<= 4; 59 60 uint32_t dest; 61 if (is_encoder) 62 dest = now_pos + (uint32_t)(i) + src; 63 else 64 dest = src - (now_pos + (uint32_t)(i)); 65 66 dest >>= 4; 67 68 inst_norm &= ~((uint64_t)(0x8FFFFF) << 13); 69 inst_norm |= (uint64_t)(dest & 0xFFFFF) << 13; 70 inst_norm |= (uint64_t)(dest & 0x100000) 71 << (36 - 20); 72 73 instruction &= (1U << bit_res) - 1; 74 instruction |= (inst_norm << bit_res); 75 76 for (size_t j = 0; j < 6; j++) 77 buffer[i + j + byte_pos] = (uint8_t)( 78 instruction 79 >> (8 * j)); 80 } 81 } 82 } 83 84 return i; 85 } 86 87 88 static lzma_ret 89 ia64_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, 90 const lzma_filter_info *filters, bool is_encoder) 91 { 92 return lzma_simple_coder_init(next, allocator, filters, 93 &ia64_code, 0, 16, 16, is_encoder); 94 } 95 96 97 #ifdef HAVE_ENCODER_IA64 98 extern lzma_ret 99 lzma_simple_ia64_encoder_init(lzma_next_coder *next, 100 const lzma_allocator *allocator, 101 const lzma_filter_info *filters) 102 { 103 return ia64_coder_init(next, allocator, filters, true); 104 } 105 #endif 106 107 108 #ifdef HAVE_DECODER_IA64 109 extern lzma_ret 110 lzma_simple_ia64_decoder_init(lzma_next_coder *next, 111 const lzma_allocator *allocator, 112 const lzma_filter_info *filters) 113 { 114 return ia64_coder_init(next, allocator, filters, false); 115 } 116 #endif 117