Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: courgette/disassembler_elf_32_arm.cc

Issue 1543643002: Switch to standard integer types in courgette/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « courgette/disassembler_elf_32_arm.h ('k') | courgette/disassembler_elf_32_x86.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <stddef.h>
8 #include <stdint.h>
9
7 #include <algorithm> 10 #include <algorithm>
8 #include <string> 11 #include <string>
9 #include <vector> 12 #include <vector>
10 13
11 #include "base/basictypes.h"
12 #include "base/logging.h" 14 #include "base/logging.h"
13 15
14 #include "courgette/assembly_program.h" 16 #include "courgette/assembly_program.h"
15 #include "courgette/courgette.h" 17 #include "courgette/courgette.h"
16 #include "courgette/encoded_program.h" 18 #include "courgette/encoded_program.h"
17 19
18 namespace courgette { 20 namespace courgette {
19 21
20 CheckBool DisassemblerElf32ARM::Compress(ARM_RVA type, uint32 arm_op, RVA rva, 22 CheckBool DisassemblerElf32ARM::Compress(ARM_RVA type,
21 uint16* c_op, uint32* addr) { 23 uint32_t arm_op,
24 RVA rva,
25 uint16_t* c_op,
26 uint32_t* addr) {
22 // This method takes an ARM or thumb opcode, extracts the relative 27 // This method takes an ARM or thumb opcode, extracts the relative
23 // target address from it (addr), and creates a corresponding 28 // target address from it (addr), and creates a corresponding
24 // Courgette opcode (c_op). 29 // Courgette opcode (c_op).
25 // 30 //
26 // Details on ARM the opcodes, and how the relative targets are 31 // Details on ARM the opcodes, and how the relative targets are
27 // computed were taken from the "ARM Architecture Reference Manual", 32 // computed were taken from the "ARM Architecture Reference Manual",
28 // section A4.1.5 and the "Thumb-2 supplement", section 4.6.12. 33 // section A4.1.5 and the "Thumb-2 supplement", section 4.6.12.
29 // ARM_OFF24 is for the ARM opcode. The rest are for thumb opcodes. 34 // ARM_OFF24 is for the ARM opcode. The rest are for thumb opcodes.
30 switch (type) { 35 switch (type) {
31 case ARM_OFF8: { 36 case ARM_OFF8: {
32 // The offset is given by lower 8 bits of the op. It is a 9-bit 37 // 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. 38 // offset, shifted right one bit and signed extended.
34 uint32 temp = (arm_op & 0x00FF) << 1; 39 uint32_t temp = (arm_op & 0x00FF) << 1;
35 if (temp & 0x0100) 40 if (temp & 0x0100)
36 temp |= 0xFFFFFE00; 41 temp |= 0xFFFFFE00;
37 temp += 4; // Offset from _next_ PC. 42 temp += 4; // Offset from _next_ PC.
38 fflush(stdout); 43 fflush(stdout);
39 44
40 (*addr) = temp; 45 (*addr) = temp;
41 (*c_op) = static_cast<uint16>(arm_op >> 8) | 0x1000; 46 (*c_op) = static_cast<uint16_t>(arm_op >> 8) | 0x1000;
42 break; 47 break;
43 } 48 }
44 case ARM_OFF11: { 49 case ARM_OFF11: {
45 // The offset is given by lower 11 bits of the op, and is a 50 // 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. 51 // 12-bit offset, shifted right one bit and sign extended.
47 uint32 temp = (arm_op & 0x07FF) << 1; 52 uint32_t temp = (arm_op & 0x07FF) << 1;
48 if (temp & 0x00000800) 53 if (temp & 0x00000800)
49 temp |= 0xFFFFF000; 54 temp |= 0xFFFFF000;
50 temp += 4; // Offset from _next_ PC. 55 temp += 4; // Offset from _next_ PC.
51 56
52 (*addr) = temp; 57 (*addr) = temp;
53 (*c_op) = static_cast<uint16>(arm_op >> 11) | 0x2000; 58 (*c_op) = static_cast<uint16_t>(arm_op >> 11) | 0x2000;
54 break; 59 break;
55 } 60 }
56 case ARM_OFF24: { 61 case ARM_OFF24: {
57 // The offset is given by the lower 24-bits of the op, shifted 62 // The offset is given by the lower 24-bits of the op, shifted
58 // left 2 bits, and sign extended. 63 // left 2 bits, and sign extended.
59 uint32 temp = (arm_op & 0x00FFFFFF) << 2; 64 uint32_t temp = (arm_op & 0x00FFFFFF) << 2;
60 if (temp & 0x02000000) 65 if (temp & 0x02000000)
61 temp |= 0xFC000000; 66 temp |= 0xFC000000;
62 temp += 8; 67 temp += 8;
63 68
64 (*addr) = temp; 69 (*addr) = temp;
65 (*c_op) = (arm_op >> 24) | 0x3000; 70 (*c_op) = (arm_op >> 24) | 0x3000;
66 break; 71 break;
67 } 72 }
68 case ARM_OFF25: { 73 case ARM_OFF25: {
69 uint32 temp = 0; 74 uint32_t temp = 0;
70 temp |= (arm_op & 0x000007FF) << 1; // imm11 75 temp |= (arm_op & 0x000007FF) << 1; // imm11
71 temp |= (arm_op & 0x03FF0000) >> 4; // imm10 76 temp |= (arm_op & 0x03FF0000) >> 4; // imm10
72 77
73 uint32 S = (arm_op & (1 << 26)) >> 26; 78 uint32_t S = (arm_op & (1 << 26)) >> 26;
74 uint32 j2 = (arm_op & (1 << 11)) >> 11; 79 uint32_t j2 = (arm_op & (1 << 11)) >> 11;
75 uint32 j1 = (arm_op & (1 << 13)) >> 13; 80 uint32_t j1 = (arm_op & (1 << 13)) >> 13;
76 bool bit12 = ((arm_op & (1 << 12)) >> 12) != 0; 81 bool bit12 = ((arm_op & (1 << 12)) >> 12) != 0;
77 bool bit14 = ((arm_op & (1 << 14)) >> 14) != 0; 82 bool bit14 = ((arm_op & (1 << 14)) >> 14) != 0;
78 83
79 uint32 i2 = ~(j2 ^ S) & 1; 84 uint32_t i2 = ~(j2 ^ S) & 1;
80 uint32 i1 = ~(j1 ^ S) & 1; 85 uint32_t i1 = ~(j1 ^ S) & 1;
81 bool toARM = bit14 && !bit12; 86 bool toARM = bit14 && !bit12;
82 87
83 temp |= (S << 24) | (i1 << 23) | (i2 << 22); 88 temp |= (S << 24) | (i1 << 23) | (i2 << 22);
84 89
85 if (temp & 0x01000000) // sign extension 90 if (temp & 0x01000000) // sign extension
86 temp |= 0xFE000000; 91 temp |= 0xFE000000;
87 uint32 prefetch; 92 uint32_t prefetch;
88 if (toARM) { 93 if (toARM) {
89 // Align PC on 4-byte boundary 94 // Align PC on 4-byte boundary
90 uint32 align4byte = (rva % 4) ? 2 : 4; 95 uint32_t align4byte = (rva % 4) ? 2 : 4;
91 prefetch = align4byte; 96 prefetch = align4byte;
92 } else { 97 } else {
93 prefetch = 4; 98 prefetch = 4;
94 } 99 }
95 temp += prefetch; 100 temp += prefetch;
96 (*addr) = temp; 101 (*addr) = temp;
97 102
98 uint32 temp2 = 0x4000; 103 uint32_t temp2 = 0x4000;
99 temp2 |= (arm_op & (1 << 12)) >> 12; 104 temp2 |= (arm_op & (1 << 12)) >> 12;
100 temp2 |= (arm_op & (1 << 14)) >> 13; 105 temp2 |= (arm_op & (1 << 14)) >> 13;
101 temp2 |= (arm_op & (1 << 15)) >> 13; 106 temp2 |= (arm_op & (1 << 15)) >> 13;
102 temp2 |= (arm_op & 0xF8000000) >> 24; 107 temp2 |= (arm_op & 0xF8000000) >> 24;
103 temp2 |= (prefetch & 0x0000000F) << 8; 108 temp2 |= (prefetch & 0x0000000F) << 8;
104 (*c_op) = static_cast<uint16>(temp2); 109 (*c_op) = static_cast<uint16_t>(temp2);
105 break; 110 break;
106 } 111 }
107 case ARM_OFF21: { 112 case ARM_OFF21: {
108 uint32 temp = 0; 113 uint32_t temp = 0;
109 temp |= (arm_op & 0x000007FF) << 1; // imm11 114 temp |= (arm_op & 0x000007FF) << 1; // imm11
110 temp |= (arm_op & 0x003F0000) >> 4; // imm6 115 temp |= (arm_op & 0x003F0000) >> 4; // imm6
111 116
112 uint32 S = (arm_op & (1 << 26)) >> 26; 117 uint32_t S = (arm_op & (1 << 26)) >> 26;
113 uint32 j2 = (arm_op & (1 << 11)) >> 11; 118 uint32_t j2 = (arm_op & (1 << 11)) >> 11;
114 uint32 j1 = (arm_op & (1 << 13)) >> 13; 119 uint32_t j1 = (arm_op & (1 << 13)) >> 13;
115 120
116 temp |= (S << 20) | (j1 << 19) | (j2 << 18); 121 temp |= (S << 20) | (j1 << 19) | (j2 << 18);
117 122
118 if (temp & 0x00100000) // sign extension 123 if (temp & 0x00100000) // sign extension
119 temp |= 0xFFE00000; 124 temp |= 0xFFE00000;
120 temp += 4; 125 temp += 4;
121 (*addr) = temp; 126 (*addr) = temp;
122 127
123 uint32 temp2 = 0x5000; 128 uint32_t temp2 = 0x5000;
124 temp2 |= (arm_op & 0x03C00000) >> 22; // just save the cond 129 temp2 |= (arm_op & 0x03C00000) >> 22; // just save the cond
125 (*c_op) = static_cast<uint16>(temp2); 130 (*c_op) = static_cast<uint16_t>(temp2);
126 break; 131 break;
127 } 132 }
128 default: 133 default:
129 return false; 134 return false;
130 } 135 }
131 return true; 136 return true;
132 } 137 }
133 138
134 CheckBool DisassemblerElf32ARM::Decompress(ARM_RVA type, uint16 c_op, 139 CheckBool DisassemblerElf32ARM::Decompress(ARM_RVA type,
135 uint32 addr, uint32* arm_op) { 140 uint16_t c_op,
141 uint32_t addr,
142 uint32_t* arm_op) {
136 // Reverses the process in the compress() method. Takes the 143 // Reverses the process in the compress() method. Takes the
137 // Courgette op and relative address and reconstructs the original 144 // Courgette op and relative address and reconstructs the original
138 // ARM or thumb op. 145 // ARM or thumb op.
139 switch (type) { 146 switch (type) {
140 case ARM_OFF8: 147 case ARM_OFF8:
141 (*arm_op) = ((c_op & 0x0FFF) << 8) | (((addr - 4) >> 1) & 0x000000FF); 148 (*arm_op) = ((c_op & 0x0FFF) << 8) | (((addr - 4) >> 1) & 0x000000FF);
142 break; 149 break;
143 case ARM_OFF11: 150 case ARM_OFF11:
144 (*arm_op) = ((c_op & 0x0FFF) << 11) | (((addr - 4) >> 1) & 0x000007FF); 151 (*arm_op) = ((c_op & 0x0FFF) << 11) | (((addr - 4) >> 1) & 0x000007FF);
145 break; 152 break;
146 case ARM_OFF24: 153 case ARM_OFF24:
147 (*arm_op) = ((c_op & 0x0FFF) << 24) | (((addr - 8) >> 2) & 0x00FFFFFF); 154 (*arm_op) = ((c_op & 0x0FFF) << 24) | (((addr - 8) >> 2) & 0x00FFFFFF);
148 break; 155 break;
149 case ARM_OFF25: { 156 case ARM_OFF25: {
150 uint32 temp = 0; 157 uint32_t temp = 0;
151 temp |= (c_op & (1 << 0)) << 12; 158 temp |= (c_op & (1 << 0)) << 12;
152 temp |= (c_op & (1 << 1)) << 13; 159 temp |= (c_op & (1 << 1)) << 13;
153 temp |= (c_op & (1 << 2)) << 13; 160 temp |= (c_op & (1 << 2)) << 13;
154 temp |= (c_op & (0xF8000000 >> 24)) << 24; 161 temp |= (c_op & (0xF8000000 >> 24)) << 24;
155 162
156 uint32 prefetch = (c_op & 0x0F00) >> 8; 163 uint32_t prefetch = (c_op & 0x0F00) >> 8;
157 addr -= prefetch; 164 addr -= prefetch;
158 165
159 addr &= 0x01FFFFFF; 166 addr &= 0x01FFFFFF;
160 167
161 uint32 S = (addr & (1 << 24)) >> 24; 168 uint32_t S = (addr & (1 << 24)) >> 24;
162 uint32 i1 = (addr & (1 << 23)) >> 23; 169 uint32_t i1 = (addr & (1 << 23)) >> 23;
163 uint32 i2 = (addr & (1 << 22)) >> 22; 170 uint32_t i2 = (addr & (1 << 22)) >> 22;
164 171
165 uint32 j1 = ((~i1) ^ S) & 1; 172 uint32_t j1 = ((~i1) ^ S) & 1;
166 uint32 j2 = ((~i2) ^ S) & 1; 173 uint32_t j2 = ((~i2) ^ S) & 1;
167 174
168 temp |= S << 26; 175 temp |= S << 26;
169 temp |= j2 << 11; 176 temp |= j2 << 11;
170 temp |= j1 << 13; 177 temp |= j1 << 13;
171 178
172 temp |= (addr & (0x000007FF << 1)) >> 1; 179 temp |= (addr & (0x000007FF << 1)) >> 1;
173 temp |= (addr & (0x03FF0000 >> 4)) << 4; 180 temp |= (addr & (0x03FF0000 >> 4)) << 4;
174 181
175 (*arm_op) = temp; 182 (*arm_op) = temp;
176 break; 183 break;
177 } 184 }
178 case ARM_OFF21: { 185 case ARM_OFF21: {
179 uint32 temp = 0xF0008000; 186 uint32_t temp = 0xF0008000;
180 temp |= (c_op & (0x03C00000 >> 22)) << 22; 187 temp |= (c_op & (0x03C00000 >> 22)) << 22;
181 188
182 addr -= 4; 189 addr -= 4;
183 addr &= 0x001FFFFF; 190 addr &= 0x001FFFFF;
184 191
185 uint32 S = (addr & (1 << 20)) >> 20; 192 uint32_t S = (addr & (1 << 20)) >> 20;
186 uint32 j1 = (addr & (1 << 19)) >> 19; 193 uint32_t j1 = (addr & (1 << 19)) >> 19;
187 uint32 j2 = (addr & (1 << 18)) >> 18; 194 uint32_t j2 = (addr & (1 << 18)) >> 18;
188 195
189 temp |= S << 26; 196 temp |= S << 26;
190 temp |= j2 << 11; 197 temp |= j2 << 11;
191 temp |= j1 << 13; 198 temp |= j1 << 13;
192 199
193 temp |= (addr & (0x000007FF << 1)) >> 1; 200 temp |= (addr & (0x000007FF << 1)) >> 1;
194 temp |= (addr & (0x003F0000 >> 4)) << 4; 201 temp |= (addr & (0x003F0000 >> 4)) << 4;
195 202
196 (*arm_op) = temp; 203 (*arm_op) = temp;
197 break; 204 break;
198 } 205 }
199 default: 206 default:
200 return false; 207 return false;
201 } 208 }
202 return true; 209 return true;
203 } 210 }
204 211
205 uint16 DisassemblerElf32ARM::TypedRVAARM::op_size() const { 212 uint16_t DisassemblerElf32ARM::TypedRVAARM::op_size() const {
206 switch (type_) { 213 switch (type_) {
207 case ARM_OFF8: 214 case ARM_OFF8:
208 return 2; 215 return 2;
209 case ARM_OFF11: 216 case ARM_OFF11:
210 return 2; 217 return 2;
211 case ARM_OFF24: 218 case ARM_OFF24:
212 return 4; 219 return 4;
213 case ARM_OFF25: 220 case ARM_OFF25:
214 return 4; 221 return 4;
215 case ARM_OFF21: 222 case ARM_OFF21:
216 return 4; 223 return 4;
217 default: 224 default:
218 return 0xFFFF; 225 return 0xFFFF;
219 } 226 }
220 } 227 }
221 228
222 CheckBool DisassemblerElf32ARM::TypedRVAARM::ComputeRelativeTarget( 229 CheckBool DisassemblerElf32ARM::TypedRVAARM::ComputeRelativeTarget(
223 const uint8* op_pointer) { 230 const uint8_t* op_pointer) {
224 arm_op_ = op_pointer; 231 arm_op_ = op_pointer;
225 switch (type_) { 232 switch (type_) {
226 case ARM_OFF8: 233 case ARM_OFF8:
227 // Fall through 234 // Fall through
228 case ARM_OFF11: { 235 case ARM_OFF11: {
229 RVA relative_target; 236 RVA relative_target;
230 CheckBool ret = Compress(type_, Read16LittleEndian(op_pointer), rva(), 237 CheckBool ret = Compress(type_, Read16LittleEndian(op_pointer), rva(),
231 &c_op_, &relative_target); 238 &c_op_, &relative_target);
232 set_relative_target(relative_target); 239 set_relative_target(relative_target);
233 return ret; 240 return ret;
234 } 241 }
235 case ARM_OFF24: { 242 case ARM_OFF24: {
236 RVA relative_target; 243 RVA relative_target;
237 CheckBool ret = Compress(type_, Read32LittleEndian(op_pointer), rva(), 244 CheckBool ret = Compress(type_, Read32LittleEndian(op_pointer), rva(),
238 &c_op_, &relative_target); 245 &c_op_, &relative_target);
239 set_relative_target(relative_target); 246 set_relative_target(relative_target);
240 return ret; 247 return ret;
241 } 248 }
242 case ARM_OFF25: 249 case ARM_OFF25:
243 // Fall through 250 // Fall through
244 case ARM_OFF21: { 251 case ARM_OFF21: {
245 // A thumb-2 op is 32 bits stored as two 16-bit words 252 // A thumb-2 op is 32 bits stored as two 16-bit words
246 uint32 pval = (Read16LittleEndian(op_pointer) << 16) 253 uint32_t pval = (Read16LittleEndian(op_pointer) << 16) |
247 | Read16LittleEndian(op_pointer + 2); 254 Read16LittleEndian(op_pointer + 2);
248 RVA relative_target; 255 RVA relative_target;
249 CheckBool ret = Compress(type_, pval, rva(), &c_op_, &relative_target); 256 CheckBool ret = Compress(type_, pval, rva(), &c_op_, &relative_target);
250 set_relative_target(relative_target); 257 set_relative_target(relative_target);
251 return ret; 258 return ret;
252 } 259 }
253 default: 260 default:
254 return false; 261 return false;
255 } 262 }
256 } 263 }
257 264
(...skipping 11 matching lines...) Expand all
269 } 276 }
270 277
271 // Convert an ELF relocation struction into an RVA 278 // Convert an ELF relocation struction into an RVA
272 CheckBool DisassemblerElf32ARM::RelToRVA(Elf32_Rel rel, RVA* result) const { 279 CheckBool DisassemblerElf32ARM::RelToRVA(Elf32_Rel rel, RVA* result) const {
273 280
274 // The rightmost byte of r_info is the type... 281 // The rightmost byte of r_info is the type...
275 elf32_rel_arm_type_values type = 282 elf32_rel_arm_type_values type =
276 (elf32_rel_arm_type_values)(unsigned char)rel.r_info; 283 (elf32_rel_arm_type_values)(unsigned char)rel.r_info;
277 284
278 // The other 3 bytes of r_info are the symbol 285 // The other 3 bytes of r_info are the symbol
279 uint32 symbol = rel.r_info >> 8; 286 uint32_t symbol = rel.r_info >> 8;
280 287
281 switch(type) 288 switch(type)
282 { 289 {
283 case R_ARM_RELATIVE: 290 case R_ARM_RELATIVE:
284 if (symbol != 0) 291 if (symbol != 0)
285 return false; 292 return false;
286 293
287 // This is a basic ABS32 relocation address 294 // This is a basic ABS32 relocation address
288 *result = rel.r_offset; 295 *result = rel.r_offset;
289 return true; 296 return true;
(...skipping 24 matching lines...) Expand all
314 321
315 bool match = true; 322 bool match = true;
316 323
317 // Walk all the bytes in the section, matching relocation table or not 324 // Walk all the bytes in the section, matching relocation table or not
318 size_t file_offset = section_header->sh_offset; 325 size_t file_offset = section_header->sh_offset;
319 size_t section_end = section_header->sh_offset + section_header->sh_size; 326 size_t section_end = section_header->sh_offset + section_header->sh_size;
320 327
321 Elf32_Rel *section_relocs_iter = 328 Elf32_Rel *section_relocs_iter =
322 (Elf32_Rel *)OffsetToPointer(section_header->sh_offset); 329 (Elf32_Rel *)OffsetToPointer(section_header->sh_offset);
323 330
324 uint32 section_relocs_count = section_header->sh_size / 331 uint32_t section_relocs_count =
325 section_header->sh_entsize; 332 section_header->sh_size / section_header->sh_entsize;
326 333
327 if (abs32_locations_.size() > section_relocs_count) 334 if (abs32_locations_.size() > section_relocs_count)
328 match = false; 335 match = false;
329 336
330 if (!abs32_locations_.empty()) { 337 if (!abs32_locations_.empty()) {
331 std::vector<RVA>::iterator reloc_iter = abs32_locations_.begin(); 338 std::vector<RVA>::iterator reloc_iter = abs32_locations_.begin();
332 339
333 for (uint32 i = 0; i < section_relocs_count; i++) { 340 for (uint32_t i = 0; i < section_relocs_count; i++) {
334 if (section_relocs_iter->r_offset == *reloc_iter) 341 if (section_relocs_iter->r_offset == *reloc_iter)
335 break; 342 break;
336 343
337 if (!ParseSimpleRegion(file_offset, file_offset + sizeof(Elf32_Rel), 344 if (!ParseSimpleRegion(file_offset, file_offset + sizeof(Elf32_Rel),
338 program)) 345 program))
339 return false; 346 return false;
340 347
341 file_offset += sizeof(Elf32_Rel); 348 file_offset += sizeof(Elf32_Rel);
342 ++section_relocs_iter; 349 ++section_relocs_iter;
343 } 350 }
(...skipping 13 matching lines...) Expand all
357 if (!program->EmitElfARMRelocationInstruction()) 364 if (!program->EmitElfARMRelocationInstruction())
358 return false; 365 return false;
359 } 366 }
360 } 367 }
361 368
362 return ParseSimpleRegion(file_offset, section_end, program); 369 return ParseSimpleRegion(file_offset, section_end, program);
363 } 370 }
364 371
365 CheckBool DisassemblerElf32ARM::ParseRel32RelocsFromSection( 372 CheckBool DisassemblerElf32ARM::ParseRel32RelocsFromSection(
366 const Elf32_Shdr* section_header) { 373 const Elf32_Shdr* section_header) {
374 uint32_t start_file_offset = section_header->sh_offset;
375 uint32_t end_file_offset = start_file_offset + section_header->sh_size;
367 376
368 uint32 start_file_offset = section_header->sh_offset; 377 const uint8_t* start_pointer = OffsetToPointer(start_file_offset);
369 uint32 end_file_offset = start_file_offset + section_header->sh_size; 378 const uint8_t* end_pointer = OffsetToPointer(end_file_offset);
370
371 const uint8* start_pointer = OffsetToPointer(start_file_offset);
372 const uint8* end_pointer = OffsetToPointer(end_file_offset);
373 379
374 // Quick way to convert from Pointer to RVA within a single Section is to 380 // Quick way to convert from Pointer to RVA within a single Section is to
375 // subtract 'pointer_to_rva'. 381 // subtract 'pointer_to_rva'.
376 const uint8* const adjust_pointer_to_rva = start_pointer - 382 const uint8_t* const adjust_pointer_to_rva =
377 section_header->sh_addr; 383 start_pointer - section_header->sh_addr;
378 384
379 // Find the rel32 relocations. 385 // Find the rel32 relocations.
380 const uint8* p = start_pointer; 386 const uint8_t* p = start_pointer;
381 bool on_32bit = 1; // 32-bit ARM ops appear on 32-bit boundaries, so track it 387 bool on_32bit = 1; // 32-bit ARM ops appear on 32-bit boundaries, so track it
382 while (p < end_pointer) { 388 while (p < end_pointer) {
383 // Heuristic discovery of rel32 locations in instruction stream: are the 389 // Heuristic discovery of rel32 locations in instruction stream: are the
384 // next few bytes the start of an instruction containing a rel32 390 // next few bytes the start of an instruction containing a rel32
385 // addressing mode? 391 // addressing mode?
386 392
387 TypedRVAARM* rel32_rva = NULL; 393 TypedRVAARM* rel32_rva = NULL;
388 RVA target_rva = 0; 394 RVA target_rva = 0;
389 bool found = false; 395 bool found = false;
390 396
391 // 16-bit thumb ops 397 // 16-bit thumb ops
392 if (!found && (p + 3) <= end_pointer) { 398 if (!found && (p + 3) <= end_pointer) {
393 uint16 pval = Read16LittleEndian(p); 399 uint16_t pval = Read16LittleEndian(p);
394 if ((pval & 0xF000) == 0xD000) { 400 if ((pval & 0xF000) == 0xD000) {
395 RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva); 401 RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva);
396 402
397 rel32_rva = new TypedRVAARM(ARM_OFF8, rva); 403 rel32_rva = new TypedRVAARM(ARM_OFF8, rva);
398 if (!rel32_rva->ComputeRelativeTarget((uint8*) p)) { 404 if (!rel32_rva->ComputeRelativeTarget((uint8_t*)p)) {
399 return false; 405 return false;
400 } 406 }
401 target_rva = rel32_rva->rva() + rel32_rva->relative_target(); 407 target_rva = rel32_rva->rva() + rel32_rva->relative_target();
402 found = true; 408 found = true;
403 } else if ((pval & 0xF800) == 0xE000) { 409 } else if ((pval & 0xF800) == 0xE000) {
404 RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva); 410 RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva);
405 411
406 rel32_rva = new TypedRVAARM(ARM_OFF11, rva); 412 rel32_rva = new TypedRVAARM(ARM_OFF11, rva);
407 if (!rel32_rva->ComputeRelativeTarget((uint8*) p)) { 413 if (!rel32_rva->ComputeRelativeTarget((uint8_t*)p)) {
408 return false; 414 return false;
409 } 415 }
410 target_rva = rel32_rva->rva() + rel32_rva->relative_target(); 416 target_rva = rel32_rva->rva() + rel32_rva->relative_target();
411 found = true; 417 found = true;
412 } 418 }
413 } 419 }
414 420
415 // thumb-2 ops comprised of two 16-bit words 421 // thumb-2 ops comprised of two 16-bit words
416 if (!found && (p + 5) <= end_pointer) { 422 if (!found && (p + 5) <= end_pointer) {
417 // This is really two 16-bit words, not one 32-bit word. 423 // This is really two 16-bit words, not one 32-bit word.
418 uint32 pval = (Read16LittleEndian(p) << 16) | Read16LittleEndian(p + 2); 424 uint32_t pval = (Read16LittleEndian(p) << 16) | Read16LittleEndian(p + 2);
419 if ((pval & 0xF8008000) == 0xF0008000) { 425 if ((pval & 0xF8008000) == 0xF0008000) {
420 // Covers thumb-2's 32-bit conditional/unconditional branches 426 // Covers thumb-2's 32-bit conditional/unconditional branches
421 427
422 if ( (pval & (1 << 14)) || (pval & (1 << 12)) ) { 428 if ( (pval & (1 << 14)) || (pval & (1 << 12)) ) {
423 // A branch, with link, or with link and exchange. 429 // A branch, with link, or with link and exchange.
424 RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva); 430 RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva);
425 431
426 rel32_rva = new TypedRVAARM(ARM_OFF25, rva); 432 rel32_rva = new TypedRVAARM(ARM_OFF25, rva);
427 if (!rel32_rva->ComputeRelativeTarget((uint8*) p)) { 433 if (!rel32_rva->ComputeRelativeTarget((uint8_t*)p)) {
428 return false; 434 return false;
429 } 435 }
430 target_rva = rel32_rva->rva() + rel32_rva->relative_target(); 436 target_rva = rel32_rva->rva() + rel32_rva->relative_target();
431 found = true; 437 found = true;
432 } else { 438 } else {
433 // TODO(paulgazz) make sure cond is not 111 439 // TODO(paulgazz) make sure cond is not 111
434 // A conditional branch instruction 440 // A conditional branch instruction
435 RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva); 441 RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva);
436 442
437 rel32_rva = new TypedRVAARM(ARM_OFF21, rva); 443 rel32_rva = new TypedRVAARM(ARM_OFF21, rva);
438 if (!rel32_rva->ComputeRelativeTarget((uint8*) p)) { 444 if (!rel32_rva->ComputeRelativeTarget((uint8_t*)p)) {
439 return false; 445 return false;
440 } 446 }
441 target_rva = rel32_rva->rva() + rel32_rva->relative_target(); 447 target_rva = rel32_rva->rva() + rel32_rva->relative_target();
442 found = true; 448 found = true;
443 } 449 }
444 } 450 }
445 } 451 }
446 452
447 // 32-bit ARM ops 453 // 32-bit ARM ops
448 if (!found && on_32bit && (p + 5) <= end_pointer) { 454 if (!found && on_32bit && (p + 5) <= end_pointer) {
449 uint32 pval = Read32LittleEndian(p); 455 uint32_t pval = Read32LittleEndian(p);
450 if ((pval & 0x0E000000) == 0x0A000000) { 456 if ((pval & 0x0E000000) == 0x0A000000) {
451 // Covers both 0x0A 0x0B ARM relative branches 457 // Covers both 0x0A 0x0B ARM relative branches
452 RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva); 458 RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva);
453 459
454 rel32_rva = new TypedRVAARM(ARM_OFF24, rva); 460 rel32_rva = new TypedRVAARM(ARM_OFF24, rva);
455 if (!rel32_rva->ComputeRelativeTarget((uint8*) p)) { 461 if (!rel32_rva->ComputeRelativeTarget((uint8_t*)p)) {
456 return false; 462 return false;
457 } 463 }
458 target_rva = rel32_rva->rva() + rel32_rva->relative_target(); 464 target_rva = rel32_rva->rva() + rel32_rva->relative_target();
459 found = true; 465 found = true;
460 } 466 }
461 } 467 }
462 468
463 if (found && IsValidRVA(target_rva)) { 469 if (found && IsValidRVA(target_rva)) {
464 rel32_locations_.push_back(rel32_rva); 470 rel32_locations_.push_back(rel32_rva);
465 #if COURGETTE_HISTOGRAM_TARGETS 471 #if COURGETTE_HISTOGRAM_TARGETS
(...skipping 13 matching lines...) Expand all
479 // Move 2 bytes at a time, but track 32-bit boundaries 485 // Move 2 bytes at a time, but track 32-bit boundaries
480 p += 2; 486 p += 2;
481 on_32bit = ((on_32bit + 1) % 2) != 0; 487 on_32bit = ((on_32bit + 1) % 2) != 0;
482 } 488 }
483 } 489 }
484 490
485 return true; 491 return true;
486 } 492 }
487 493
488 } // namespace courgette 494 } // namespace courgette
OLDNEW
« no previous file with comments | « courgette/disassembler_elf_32_arm.h ('k') | courgette/disassembler_elf_32_x86.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698