1// Copyright 2007-2008 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_DIAGNOSTICS_DISASM_H_
6#define V8_DIAGNOSTICS_DISASM_H_
7
8#include "src/base/vector.h"
9
10namespace disasm {
11
12using byte = unsigned char;
13
14// Interface and default implementation for converting addresses and
15// register-numbers to text.  The default implementation is machine
16// specific.
17class V8_EXPORT_PRIVATE NameConverter {
18 public:
19  virtual ~NameConverter() = default;
20  virtual const char* NameOfCPURegister(int reg) const;
21  virtual const char* NameOfByteCPURegister(int reg) const;
22  virtual const char* NameOfXMMRegister(int reg) const;
23  virtual const char* NameOfAddress(byte* addr) const;
24  virtual const char* NameOfConstant(byte* addr) const;
25  virtual const char* NameInCode(byte* addr) const;
26
27  // Given a root-register-relative offset, returns either a name or nullptr if
28  // none is found.
29  // TODO(jgruber,v8:7989): This is a temporary solution until we can preserve
30  // code comments through snapshotting.
31  virtual const char* RootRelativeName(int offset) const { UNREACHABLE(); }
32
33 protected:
34  v8::base::EmbeddedVector<char, 128> tmp_buffer_;
35};
36
37// A generic Disassembler interface
38class Disassembler {
39 public:
40  enum UnimplementedOpcodeAction : int8_t {
41    kContinueOnUnimplementedOpcode,
42    kAbortOnUnimplementedOpcode
43  };
44
45  // Caller deallocates converter.
46  explicit Disassembler(const NameConverter& converter,
47                        UnimplementedOpcodeAction unimplemented_opcode_action =
48                            kAbortOnUnimplementedOpcode)
49      : converter_(converter),
50        unimplemented_opcode_action_(unimplemented_opcode_action) {}
51
52  UnimplementedOpcodeAction unimplemented_opcode_action() const {
53    return unimplemented_opcode_action_;
54  }
55
56  // Writes one disassembled instruction into 'buffer' (0-terminated).
57  // Returns the length of the disassembled machine instruction in bytes.
58  V8_EXPORT_PRIVATE int InstructionDecode(v8::base::Vector<char> buffer,
59                                          byte* instruction);
60
61  // Returns -1 if instruction does not mark the beginning of a constant pool,
62  // or the number of entries in the constant pool beginning here.
63  int ConstantPoolSizeAt(byte* instruction);
64
65  // Write disassembly into specified file 'f' using specified NameConverter
66  // (see constructor).
67  V8_EXPORT_PRIVATE static void Disassemble(
68      FILE* f, byte* begin, byte* end,
69      UnimplementedOpcodeAction unimplemented_action =
70          kAbortOnUnimplementedOpcode);
71
72 private:
73  const NameConverter& converter_;
74  const UnimplementedOpcodeAction unimplemented_opcode_action_;
75
76  DISALLOW_IMPLICIT_CONSTRUCTORS(Disassembler);
77};
78
79}  // namespace disasm
80
81#endif  // V8_DIAGNOSTICS_DISASM_H_
82