OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "courgette/disassembler_elf_32_arm.h" | 5 #include "courgette/disassembler_elf_32_arm.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 20 matching lines...) Expand all Loading... |
31 case ARM_OFF8: { | 31 case ARM_OFF8: { |
32 // The offset is given by lower 8 bits of the op. It is a 9-bit | 32 // The offset is given by lower 8 bits of the op. It is a 9-bit |
33 // offset, shifted right one bit and signed extended. | 33 // offset, shifted right one bit and signed extended. |
34 uint32 temp = (arm_op & 0x00FF) << 1; | 34 uint32 temp = (arm_op & 0x00FF) << 1; |
35 if (temp & 0x0100) | 35 if (temp & 0x0100) |
36 temp |= 0xFFFFFE00; | 36 temp |= 0xFFFFFE00; |
37 temp += 4; // Offset from _next_ PC. | 37 temp += 4; // Offset from _next_ PC. |
38 fflush(stdout); | 38 fflush(stdout); |
39 | 39 |
40 (*addr) = temp; | 40 (*addr) = temp; |
41 (*c_op) = (arm_op >> 8) | 0x1000; | 41 (*c_op) = static_cast<uint16>(arm_op >> 8) | 0x1000; |
42 break; | 42 break; |
43 } | 43 } |
44 case ARM_OFF11: { | 44 case ARM_OFF11: { |
45 // The offset is given by lower 11 bits of the op, and is a | 45 // The offset is given by lower 11 bits of the op, and is a |
46 // 12-bit offset, shifted right one bit and sign extended. | 46 // 12-bit offset, shifted right one bit and sign extended. |
47 uint32 temp = (arm_op & 0x07FF) << 1; | 47 uint32 temp = (arm_op & 0x07FF) << 1; |
48 if (temp & 0x00000800) | 48 if (temp & 0x00000800) |
49 temp |= 0xFFFFF000; | 49 temp |= 0xFFFFF000; |
50 temp += 4; // Offset from _next_ PC. | 50 temp += 4; // Offset from _next_ PC. |
51 | 51 |
52 (*addr) = temp; | 52 (*addr) = temp; |
53 (*c_op) = (arm_op >> 11) | 0x2000; | 53 (*c_op) = static_cast<uint16>(arm_op >> 11) | 0x2000; |
54 break; | 54 break; |
55 } | 55 } |
56 case ARM_OFF24: { | 56 case ARM_OFF24: { |
57 // The offset is given by the lower 24-bits of the op, shifted | 57 // The offset is given by the lower 24-bits of the op, shifted |
58 // left 2 bits, and sign extended. | 58 // left 2 bits, and sign extended. |
59 uint32 temp = (arm_op & 0x00FFFFFF) << 2; | 59 uint32 temp = (arm_op & 0x00FFFFFF) << 2; |
60 if (temp & 0x02000000) | 60 if (temp & 0x02000000) |
61 temp |= 0xFC000000; | 61 temp |= 0xFC000000; |
62 temp += 8; | 62 temp += 8; |
63 | 63 |
(...skipping 30 matching lines...) Expand all Loading... |
94 } | 94 } |
95 temp += prefetch; | 95 temp += prefetch; |
96 (*addr) = temp; | 96 (*addr) = temp; |
97 | 97 |
98 uint32 temp2 = 0x4000; | 98 uint32 temp2 = 0x4000; |
99 temp2 |= (arm_op & (1 << 12)) >> 12; | 99 temp2 |= (arm_op & (1 << 12)) >> 12; |
100 temp2 |= (arm_op & (1 << 14)) >> 13; | 100 temp2 |= (arm_op & (1 << 14)) >> 13; |
101 temp2 |= (arm_op & (1 << 15)) >> 13; | 101 temp2 |= (arm_op & (1 << 15)) >> 13; |
102 temp2 |= (arm_op & 0xF8000000) >> 24; | 102 temp2 |= (arm_op & 0xF8000000) >> 24; |
103 temp2 |= (prefetch & 0x0000000F) << 8; | 103 temp2 |= (prefetch & 0x0000000F) << 8; |
104 (*c_op) = temp2; | 104 (*c_op) = static_cast<uint16>(temp2); |
105 break; | 105 break; |
106 } | 106 } |
107 case ARM_OFF21: { | 107 case ARM_OFF21: { |
108 uint32 temp = 0; | 108 uint32 temp = 0; |
109 temp |= (arm_op & 0x000007FF) << 1; // imm11 | 109 temp |= (arm_op & 0x000007FF) << 1; // imm11 |
110 temp |= (arm_op & 0x003F0000) >> 4; // imm6 | 110 temp |= (arm_op & 0x003F0000) >> 4; // imm6 |
111 | 111 |
112 uint32 S = (arm_op & (1 << 26)) >> 26; | 112 uint32 S = (arm_op & (1 << 26)) >> 26; |
113 uint32 j2 = (arm_op & (1 << 11)) >> 11; | 113 uint32 j2 = (arm_op & (1 << 11)) >> 11; |
114 uint32 j1 = (arm_op & (1 << 13)) >> 13; | 114 uint32 j1 = (arm_op & (1 << 13)) >> 13; |
115 | 115 |
116 temp |= (S << 20) | (j1 << 19) | (j2 << 18); | 116 temp |= (S << 20) | (j1 << 19) | (j2 << 18); |
117 | 117 |
118 if (temp & 0x00100000) // sign extension | 118 if (temp & 0x00100000) // sign extension |
119 temp |= 0xFFE00000; | 119 temp |= 0xFFE00000; |
120 temp += 4; | 120 temp += 4; |
121 (*addr) = temp; | 121 (*addr) = temp; |
122 | 122 |
123 uint32 temp2 = 0x5000; | 123 uint32 temp2 = 0x5000; |
124 temp2 |= (arm_op & 0x03C00000) >> 22; // just save the cond | 124 temp2 |= (arm_op & 0x03C00000) >> 22; // just save the cond |
125 (*c_op) = temp2; | 125 (*c_op) = static_cast<uint16>(temp2); |
126 break; | 126 break; |
127 } | 127 } |
128 default: | 128 default: |
129 return false; | 129 return false; |
130 } | 130 } |
131 return true; | 131 return true; |
132 } | 132 } |
133 | 133 |
134 CheckBool DisassemblerElf32ARM::Decompress(ARM_RVA type, uint16 c_op, | 134 CheckBool DisassemblerElf32ARM::Decompress(ARM_RVA type, uint16 c_op, |
135 uint32 addr, uint32* arm_op) { | 135 uint32 addr, uint32* arm_op) { |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 // Move 2 bytes at a time, but track 32-bit boundaries | 479 // Move 2 bytes at a time, but track 32-bit boundaries |
480 p += 2; | 480 p += 2; |
481 on_32bit = ((on_32bit + 1) % 2) != 0; | 481 on_32bit = ((on_32bit + 1) % 2) != 0; |
482 } | 482 } |
483 } | 483 } |
484 | 484 |
485 return true; | 485 return true; |
486 } | 486 } |
487 | 487 |
488 } // namespace courgette | 488 } // namespace courgette |
OLD | NEW |