| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/disassembler.h" | 5 #include "vm/disassembler.h" |
| 6 | 6 |
| 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. | 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 8 #if defined(TARGET_ARCH_ARM) | 8 #if defined(TARGET_ARCH_ARM) |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 | 10 |
| 11 namespace dart { | 11 namespace dart { |
| 12 | 12 |
| 13 class ARMDecoder : public ValueObject { | 13 class ARMDecoder : public ValueObject { |
| 14 public: | 14 public: |
| 15 ARMDecoder(char* buffer, size_t buffer_size) | 15 ARMDecoder(char* buffer, size_t buffer_size) |
| 16 : buffer_(buffer), | 16 : buffer_(buffer), |
| 17 buffer_size_(buffer_size), | 17 buffer_size_(buffer_size), |
| 18 buffer_pos_(0), | 18 buffer_pos_(0) { |
| 19 decode_failure_(false) { | |
| 20 buffer_[buffer_pos_] = '\0'; | 19 buffer_[buffer_pos_] = '\0'; |
| 21 } | 20 } |
| 22 | 21 |
| 23 ~ARMDecoder() {} | 22 ~ARMDecoder() {} |
| 24 | 23 |
| 25 // Writes one disassembled instruction into 'buffer' (0-terminated). | 24 // Writes one disassembled instruction into 'buffer' (0-terminated). |
| 26 // Returns true if the instruction was successfully decoded, false otherwise. | 25 // Returns true if the instruction was successfully decoded, false otherwise. |
| 27 void InstructionDecode(uword pc); | 26 void InstructionDecode(uword pc); |
| 28 | 27 |
| 29 void set_decode_failure(bool b) { decode_failure_ = b; } | |
| 30 bool decode_failure() const { return decode_failure_; } | |
| 31 | |
| 32 private: | 28 private: |
| 33 // Bottleneck functions to print into the out_buffer. | 29 // Bottleneck functions to print into the out_buffer. |
| 34 void Print(const char* str); | 30 void Print(const char* str); |
| 35 | 31 |
| 36 // Printing of common values. | 32 // Printing of common values. |
| 37 void PrintRegister(int reg); | 33 void PrintRegister(int reg); |
| 38 void PrintSRegister(int reg); | 34 void PrintSRegister(int reg); |
| 39 void PrintDRegister(int reg); | 35 void PrintDRegister(int reg); |
| 40 void PrintCondition(Instr* instr); | 36 void PrintCondition(Instr* instr); |
| 41 void PrintShiftRm(Instr* instr); | 37 void PrintShiftRm(Instr* instr); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 64 | 60 |
| 65 // Convenience functions. | 61 // Convenience functions. |
| 66 char* get_buffer() const { return buffer_; } | 62 char* get_buffer() const { return buffer_; } |
| 67 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } | 63 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } |
| 68 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } | 64 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } |
| 69 | 65 |
| 70 char* buffer_; // Decode instructions into this buffer. | 66 char* buffer_; // Decode instructions into this buffer. |
| 71 size_t buffer_size_; // The size of the character buffer. | 67 size_t buffer_size_; // The size of the character buffer. |
| 72 size_t buffer_pos_; // Current character position in buffer. | 68 size_t buffer_pos_; // Current character position in buffer. |
| 73 | 69 |
| 74 bool decode_failure_; // Set to true when a failure to decode is detected. | |
| 75 | |
| 76 DISALLOW_ALLOCATION(); | 70 DISALLOW_ALLOCATION(); |
| 77 DISALLOW_COPY_AND_ASSIGN(ARMDecoder); | 71 DISALLOW_COPY_AND_ASSIGN(ARMDecoder); |
| 78 }; | 72 }; |
| 79 | 73 |
| 80 | 74 |
| 81 // Support for assertions in the ARMDecoder formatting functions. | 75 // Support for assertions in the ARMDecoder formatting functions. |
| 82 #define STRING_STARTS_WITH(string, compare_string) \ | 76 #define STRING_STARTS_WITH(string, compare_string) \ |
| 83 (strncmp(string, compare_string, strlen(compare_string)) == 0) | 77 (strncmp(string, compare_string, strlen(compare_string)) == 0) |
| 84 | 78 |
| 85 | 79 |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 cur = *format++; | 566 cur = *format++; |
| 573 } | 567 } |
| 574 buffer_[buffer_pos_] = '\0'; | 568 buffer_[buffer_pos_] = '\0'; |
| 575 } | 569 } |
| 576 | 570 |
| 577 | 571 |
| 578 // For currently unimplemented decodings the disassembler calls Unknown(instr) | 572 // For currently unimplemented decodings the disassembler calls Unknown(instr) |
| 579 // which will just print "unknown" of the instruction bits. | 573 // which will just print "unknown" of the instruction bits. |
| 580 void ARMDecoder::Unknown(Instr* instr) { | 574 void ARMDecoder::Unknown(Instr* instr) { |
| 581 Format(instr, "unknown"); | 575 Format(instr, "unknown"); |
| 582 set_decode_failure(true); | |
| 583 } | 576 } |
| 584 | 577 |
| 585 | 578 |
| 586 void ARMDecoder::DecodeType01(Instr* instr) { | 579 void ARMDecoder::DecodeType01(Instr* instr) { |
| 587 if (!instr->IsDataProcessing()) { | 580 if (!instr->IsDataProcessing()) { |
| 588 // miscellaneous, multiply, sync primitives, extra loads and stores. | 581 // miscellaneous, multiply, sync primitives, extra loads and stores. |
| 589 if (instr->IsMiscellaneous()) { | 582 if (instr->IsMiscellaneous()) { |
| 590 switch (instr->Bits(4, 3)) { | 583 switch (instr->Bits(4, 3)) { |
| 591 case 1: { | 584 case 1: { |
| 592 if (instr->Bits(21, 2) == 0x3) { | 585 if (instr->Bits(21, 2) == 0x3) { |
| (...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 default: { | 1253 default: { |
| 1261 // The type field is 3-bits in the ARM encoding. | 1254 // The type field is 3-bits in the ARM encoding. |
| 1262 UNREACHABLE(); | 1255 UNREACHABLE(); |
| 1263 break; | 1256 break; |
| 1264 } | 1257 } |
| 1265 } | 1258 } |
| 1266 } | 1259 } |
| 1267 } | 1260 } |
| 1268 | 1261 |
| 1269 | 1262 |
| 1270 bool Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size, | 1263 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size, |
| 1271 char* human_buffer, intptr_t human_size, | 1264 char* human_buffer, intptr_t human_size, |
| 1272 int* out_instr_size, uword pc) { | 1265 int* out_instr_size, uword pc) { |
| 1273 ARMDecoder decoder(human_buffer, human_size); | 1266 ARMDecoder decoder(human_buffer, human_size); |
| 1274 decoder.InstructionDecode(pc); | 1267 decoder.InstructionDecode(pc); |
| 1275 int32_t instruction_bits = Instr::At(pc)->InstructionBits(); | 1268 int32_t instruction_bits = Instr::At(pc)->InstructionBits(); |
| 1276 OS::SNPrint(hex_buffer, hex_size, "%08x", instruction_bits); | 1269 OS::SNPrint(hex_buffer, hex_size, "%08x", instruction_bits); |
| 1277 if (out_instr_size) { | 1270 if (out_instr_size) { |
| 1278 *out_instr_size = Instr::kInstrSize; | 1271 *out_instr_size = Instr::kInstrSize; |
| 1279 } | 1272 } |
| 1280 return !decoder.decode_failure(); | |
| 1281 } | 1273 } |
| 1282 | 1274 |
| 1283 | 1275 |
| 1284 bool Disassembler::Disassemble(uword start, | 1276 void Disassembler::Disassemble(uword start, |
| 1285 uword end, | 1277 uword end, |
| 1286 DisassemblyFormatter* formatter, | 1278 DisassemblyFormatter* formatter, |
| 1287 const Code::Comments& comments) { | 1279 const Code::Comments& comments) { |
| 1288 ASSERT(formatter != NULL); | 1280 ASSERT(formatter != NULL); |
| 1289 bool success = true; | |
| 1290 char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form. | 1281 char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form. |
| 1291 char human_buffer[kUserReadableBufferSize]; // Human-readable instruction. | 1282 char human_buffer[kUserReadableBufferSize]; // Human-readable instruction. |
| 1292 uword pc = start; | 1283 uword pc = start; |
| 1293 intptr_t comment_finger = 0; | 1284 intptr_t comment_finger = 0; |
| 1294 while (pc < end) { | 1285 while (pc < end) { |
| 1295 const intptr_t offset = pc - start; | 1286 const intptr_t offset = pc - start; |
| 1296 while (comment_finger < comments.Length() && | 1287 while (comment_finger < comments.Length() && |
| 1297 comments.PCOffsetAt(comment_finger) <= offset) { | 1288 comments.PCOffsetAt(comment_finger) <= offset) { |
| 1298 formatter->Print( | 1289 formatter->Print( |
| 1299 " ;; %s\n", | 1290 " ;; %s\n", |
| 1300 String::Handle(comments.CommentAt(comment_finger)).ToCString()); | 1291 String::Handle(comments.CommentAt(comment_finger)).ToCString()); |
| 1301 comment_finger++; | 1292 comment_finger++; |
| 1302 } | 1293 } |
| 1303 int instruction_length; | 1294 int instruction_length; |
| 1304 bool res = DecodeInstruction(hex_buffer, sizeof(hex_buffer), | 1295 DecodeInstruction(hex_buffer, sizeof(hex_buffer), |
| 1305 human_buffer, sizeof(human_buffer), | 1296 human_buffer, sizeof(human_buffer), |
| 1306 &instruction_length, pc); | 1297 &instruction_length, pc); |
| 1307 if (!res) { | 1298 |
| 1308 success = false; | |
| 1309 } | |
| 1310 formatter->ConsumeInstruction(hex_buffer, | 1299 formatter->ConsumeInstruction(hex_buffer, |
| 1311 sizeof(hex_buffer), | 1300 sizeof(hex_buffer), |
| 1312 human_buffer, | 1301 human_buffer, |
| 1313 sizeof(human_buffer), | 1302 sizeof(human_buffer), |
| 1314 pc); | 1303 pc); |
| 1315 pc += instruction_length; | 1304 pc += instruction_length; |
| 1316 } | 1305 } |
| 1317 | |
| 1318 return success; | |
| 1319 } | 1306 } |
| 1320 | 1307 |
| 1321 } // namespace dart | 1308 } // namespace dart |
| 1322 | 1309 |
| 1323 #endif // defined TARGET_ARCH_ARM | 1310 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |