this repo has no description
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