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 <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 uint32_t j1 = (arm_op & (1 << 13)) >> 13; | 93 uint32_t j1 = (arm_op & (1 << 13)) >> 13; |
94 bool bit12 = ((arm_op & (1 << 12)) >> 12) != 0; // D | 94 bool bit12 = ((arm_op & (1 << 12)) >> 12) != 0; // D |
95 bool bit14 = ((arm_op & (1 << 14)) >> 14) != 0; // C | 95 bool bit14 = ((arm_op & (1 << 14)) >> 14) != 0; // C |
96 | 96 |
97 uint32_t i2 = ~(j2 ^ S) & 1; | 97 uint32_t i2 = ~(j2 ^ S) & 1; |
98 uint32_t i1 = ~(j1 ^ S) & 1; | 98 uint32_t i1 = ~(j1 ^ S) & 1; |
99 bool toARM = bit14 && !bit12; | 99 bool toARM = bit14 && !bit12; |
100 | 100 |
101 temp |= (S << 24) | (i1 << 23) | (i2 << 22); | 101 temp |= (S << 24) | (i1 << 23) | (i2 << 22); |
102 | 102 |
103 if (temp & 0x01000000) // sign extension | 103 if (temp & 0x01000000) // sign extension |
104 temp |= 0xFE000000; | 104 temp |= 0xFE000000; |
105 uint32_t prefetch; | 105 uint32_t prefetch; |
106 if (toARM) { | 106 if (toARM) { |
107 // Align PC on 4-byte boundary. | 107 // Align PC on 4-byte boundary. |
108 uint32_t align4byte = (rva % 4) ? 2 : 4; | 108 uint32_t align4byte = (rva % 4) ? 2 : 4; |
109 prefetch = align4byte; | 109 prefetch = align4byte; |
110 } else { | 110 } else { |
111 prefetch = 4; | 111 prefetch = 4; |
112 } | 112 } |
113 temp += prefetch; | 113 temp += prefetch; |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 CheckBool ret = Compress(type_, pval, rva(), &c_op_, &relative_target); | 292 CheckBool ret = Compress(type_, pval, rva(), &c_op_, &relative_target); |
293 set_relative_target(relative_target); | 293 set_relative_target(relative_target); |
294 return ret; | 294 return ret; |
295 } | 295 } |
296 default: | 296 default: |
297 return false; | 297 return false; |
298 } | 298 } |
299 } | 299 } |
300 | 300 |
301 CheckBool DisassemblerElf32ARM::TypedRVAARM::EmitInstruction( | 301 CheckBool DisassemblerElf32ARM::TypedRVAARM::EmitInstruction( |
302 AssemblyProgram* program, | 302 Label* label, |
303 Label* label) { | 303 InstructionReceptor* receptor) { |
304 return program->EmitRel32ARM(c_op(), label, arm_op_, op_size()); | 304 return receptor->EmitRel32ARM(c_op(), label, arm_op_, op_size()); |
305 } | 305 } |
306 | 306 |
307 DisassemblerElf32ARM::DisassemblerElf32ARM(const uint8_t* start, size_t length) | 307 DisassemblerElf32ARM::DisassemblerElf32ARM(const uint8_t* start, size_t length) |
308 : DisassemblerElf32(start, length) {} | 308 : DisassemblerElf32(start, length) {} |
309 | 309 |
310 // Convert an ELF relocation struction into an RVA. | 310 // Convert an ELF relocation struction into an RVA. |
311 CheckBool DisassemblerElf32ARM::RelToRVA(Elf32_Rel rel, RVA* result) const { | 311 CheckBool DisassemblerElf32ARM::RelToRVA(Elf32_Rel rel, RVA* result) const { |
312 // The rightmost byte of r_info is the type. | 312 // The rightmost byte of r_info is the type. |
313 elf32_rel_arm_type_values type = | 313 elf32_rel_arm_type_values type = |
314 static_cast<elf32_rel_arm_type_values>(rel.r_info & 0xFF); | 314 static_cast<elf32_rel_arm_type_values>(rel.r_info & 0xFF); |
(...skipping 10 matching lines...) Expand all Loading... |
325 *result = rel.r_offset; | 325 *result = rel.r_offset; |
326 return true; | 326 return true; |
327 | 327 |
328 default: | 328 default: |
329 return false; | 329 return false; |
330 } | 330 } |
331 } | 331 } |
332 | 332 |
333 CheckBool DisassemblerElf32ARM::ParseRelocationSection( | 333 CheckBool DisassemblerElf32ARM::ParseRelocationSection( |
334 const Elf32_Shdr* section_header, | 334 const Elf32_Shdr* section_header, |
335 AssemblyProgram* program) { | 335 InstructionReceptor* receptor) const { |
336 // This method compresses a contiguous stretch of R_ARM_RELATIVE entries in | 336 // This method compresses a contiguous stretch of R_ARM_RELATIVE entries in |
337 // the relocation table with a Courgette relocation table instruction. | 337 // the relocation table with a Courgette relocation table instruction. |
338 // It skips any entries at the beginning that appear in a section that | 338 // It skips any entries at the beginning that appear in a section that |
339 // Courgette doesn't support, e.g. INIT. | 339 // Courgette doesn't support, e.g. INIT. |
340 // | 340 // |
341 // Specifically, the entries should be | 341 // Specifically, the entries should be |
342 // (1) In the same relocation table | 342 // (1) In the same relocation table |
343 // (2) Are consecutive | 343 // (2) Are consecutive |
344 // (3) Are sorted in memory address order | 344 // (3) Are sorted in memory address order |
345 // | 345 // |
(...skipping 19 matching lines...) Expand all Loading... |
365 if (abs32_locations_.size() > section_relocs_count) | 365 if (abs32_locations_.size() > section_relocs_count) |
366 match = false; | 366 match = false; |
367 | 367 |
368 if (!abs32_locations_.empty()) { | 368 if (!abs32_locations_.empty()) { |
369 std::vector<RVA>::iterator reloc_iter = abs32_locations_.begin(); | 369 std::vector<RVA>::iterator reloc_iter = abs32_locations_.begin(); |
370 | 370 |
371 for (uint32_t i = 0; i < section_relocs_count; ++i) { | 371 for (uint32_t i = 0; i < section_relocs_count; ++i) { |
372 if (section_relocs_iter->r_offset == *reloc_iter) | 372 if (section_relocs_iter->r_offset == *reloc_iter) |
373 break; | 373 break; |
374 | 374 |
375 if (!ParseSimpleRegion(file_offset, | 375 if (!ParseSimpleRegion(file_offset, file_offset + sizeof(Elf32_Rel), |
376 file_offset + sizeof(Elf32_Rel), | 376 receptor)) { |
377 program)) { | |
378 return false; | 377 return false; |
379 } | 378 } |
380 | 379 |
381 file_offset += sizeof(Elf32_Rel); | 380 file_offset += sizeof(Elf32_Rel); |
382 ++section_relocs_iter; | 381 ++section_relocs_iter; |
383 } | 382 } |
384 | 383 |
385 while (match && (reloc_iter != abs32_locations_.end())) { | 384 while (match && (reloc_iter != abs32_locations_.end())) { |
386 if (section_relocs_iter->r_info != R_ARM_RELATIVE || | 385 if (section_relocs_iter->r_info != R_ARM_RELATIVE || |
387 section_relocs_iter->r_offset != *reloc_iter) { | 386 section_relocs_iter->r_offset != *reloc_iter) { |
388 match = false; | 387 match = false; |
389 } | 388 } |
390 | 389 |
391 ++section_relocs_iter; | 390 ++section_relocs_iter; |
392 ++reloc_iter; | 391 ++reloc_iter; |
393 file_offset += sizeof(Elf32_Rel); | 392 file_offset += sizeof(Elf32_Rel); |
394 } | 393 } |
395 | 394 |
396 if (match) { | 395 if (match) { |
397 // Skip over relocation tables | 396 // Skip over relocation tables |
398 if (!program->EmitElfARMRelocationInstruction()) | 397 if (!receptor->EmitElfARMRelocation()) |
399 return false; | 398 return false; |
400 } | 399 } |
401 } | 400 } |
402 | 401 |
403 return ParseSimpleRegion(file_offset, section_end, program); | 402 return ParseSimpleRegion(file_offset, section_end, receptor); |
404 } | 403 } |
405 | 404 |
406 // TODO(huangs): Detect and avoid overlap with abs32 addresses. | 405 // TODO(huangs): Detect and avoid overlap with abs32 addresses. |
407 CheckBool DisassemblerElf32ARM::ParseRel32RelocsFromSection( | 406 CheckBool DisassemblerElf32ARM::ParseRel32RelocsFromSection( |
408 const Elf32_Shdr* section_header) { | 407 const Elf32_Shdr* section_header) { |
409 FileOffset start_file_offset = section_header->sh_offset; | 408 FileOffset start_file_offset = section_header->sh_offset; |
410 FileOffset end_file_offset = start_file_offset + section_header->sh_size; | 409 FileOffset end_file_offset = start_file_offset + section_header->sh_size; |
411 | 410 |
412 const uint8_t* start_pointer = FileOffsetToPointer(start_file_offset); | 411 const uint8_t* start_pointer = FileOffsetToPointer(start_file_offset); |
413 const uint8_t* end_pointer = FileOffsetToPointer(end_file_offset); | 412 const uint8_t* end_pointer = FileOffsetToPointer(end_file_offset); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 // Move 2 bytes at a time, but track 32-bit boundaries | 519 // Move 2 bytes at a time, but track 32-bit boundaries |
521 p += 2; | 520 p += 2; |
522 on_32bit = ((on_32bit + 1) % 2) != 0; | 521 on_32bit = ((on_32bit + 1) % 2) != 0; |
523 } | 522 } |
524 } | 523 } |
525 | 524 |
526 return true; | 525 return true; |
527 } | 526 } |
528 | 527 |
529 } // namespace courgette | 528 } // namespace courgette |
OLD | NEW |