this repo has no description
at trunk 126 lines 3.9 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2// Copyright (c) 2013, the Dart project authors and Facebook, Inc. and its 3// affiliates. Please see the AUTHORS-Dart file for details. All rights 4// reserved. Use of this source code is governed by a BSD-style license that 5// can be found in the LICENSE-Dart file. 6 7#include "disassembler.h" 8 9#include <cinttypes> 10#include <cstdarg> 11 12#include "assembler-utils.h" 13 14namespace py { 15 16static const int kHexColumnWidth = 23; 17 18void DisassembleToStdout::consumeInstruction(char* hex_buffer, 19 intptr_t hex_size, 20 char* human_buffer, 21 intptr_t human_size, uword pc) { 22 (void)hex_size; 23 (void)human_size; 24 std::fprintf(stdout, "0x%" PRIX64 " %s", static_cast<uint64_t>(pc), 25 hex_buffer); 26 int hex_length = strlen(hex_buffer); 27 if (hex_length < kHexColumnWidth) { 28 for (int i = kHexColumnWidth - hex_length; i > 0; i--) { 29 std::fprintf(stdout, " "); 30 } 31 } 32 std::fprintf(stdout, "%s", human_buffer); 33 std::fprintf(stdout, "\n"); 34} 35 36void DisassembleToStdout::print(const char* format, ...) { 37 va_list args; 38 va_start(args, format); 39 std::vprintf(format, args); 40 va_end(args); 41} 42 43void DisassembleToMemory::consumeInstruction(char* hex_buffer, 44 intptr_t hex_size, 45 char* human_buffer, 46 intptr_t human_size, uword pc) { 47 (void)human_size; 48 (void)hex_buffer; 49 (void)hex_size; 50 (void)pc; 51 if (overflowed_) { 52 return; 53 } 54 intptr_t len = strlen(human_buffer); 55 if (remaining_ < len + 100) { 56 *buffer_++ = '.'; 57 *buffer_++ = '.'; 58 *buffer_++ = '.'; 59 *buffer_++ = '\n'; 60 *buffer_++ = '\0'; 61 overflowed_ = true; 62 return; 63 } 64 memmove(buffer_, human_buffer, len); 65 buffer_ += len; 66 remaining_ -= len; 67 *buffer_++ = '\n'; 68 remaining_--; 69 *buffer_ = '\0'; 70} 71 72void DisassembleToMemory::print(const char* format, ...) { 73 if (overflowed_) { 74 return; 75 } 76 va_list args; 77 va_start(args, format); 78 intptr_t len = std::vsnprintf(nullptr, 0, format, args); 79 va_end(args); 80 if (remaining_ < len + 100) { 81 *buffer_++ = '.'; 82 *buffer_++ = '.'; 83 *buffer_++ = '.'; 84 *buffer_++ = '\n'; 85 *buffer_++ = '\0'; 86 overflowed_ = true; 87 return; 88 } 89 va_start(args, format); 90 intptr_t len2 = std::vsnprintf(buffer_, len, format, args); 91 va_end(args); 92 DCHECK(len == len2, ""); 93 buffer_ += len; 94 remaining_ -= len; 95 *buffer_++ = '\n'; 96 remaining_--; 97 *buffer_ = '\0'; 98} 99 100void Disassembler::disassemble(uword start, uword end, 101 DisassemblyFormatter* formatter, 102 const CodeComments* comments) { 103 DCHECK(formatter != nullptr, ""); 104 char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form. 105 char human_buffer[kUserReadableBufferSize]; // Human-readable instruction. 106 uword pc = start; 107 intptr_t comment_finger = 0; 108 while (pc < end) { 109 const intptr_t offset = pc - start; 110 while (comments && comment_finger < comments->length() && 111 comments->offsetAt(comment_finger) <= offset) { 112 formatter->print(" ;; %s\n", comments->commentAt(comment_finger)); 113 comment_finger++; 114 } 115 int instruction_length; 116 decodeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer, 117 sizeof(human_buffer), &instruction_length, pc); 118 // TODO(emacs): Add flag to disassemble relative? Then use offset instead 119 // of pc. 120 formatter->consumeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer, 121 sizeof(human_buffer), pc); 122 pc += instruction_length; 123 } 124} 125 126} // namespace py