1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 Copyright (c) 2008-2017, Petr Kobalicek 3 4 This software is provided 'as-is', without any express or implied 5 warranty. In no event will the authors be held liable for any damages 6 arising from the use of this software. 7 8 Permission is granted to anyone to use this software for any purpose, 9 including commercial applications, and to alter it and redistribute it 10 freely, subject to the following restrictions: 11 12 1. The origin of this software must not be misrepresented; you must not 13 claim that you wrote the original software. If you use this software 14 in a product, an acknowledgment in the product documentation would be 15 appreciated but is not required. 16 2. Altered source versions must be plainly marked as such, and must not be 17 misrepresented as being the original software. 18 3. This notice may not be removed or altered from any source distribution. 19 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 20 #ifndef __PLUMED_asmjit_logging_h 21 #define __PLUMED_asmjit_logging_h 22 #ifdef __PLUMED_HAS_ASMJIT 23 #pragma GCC diagnostic push 24 #pragma GCC diagnostic ignored "-Wpedantic" 25 // [AsmJit] 26 // Complete x86/x64 JIT and Remote Assembler for C++. 27 // 28 // [License] 29 // Zlib - See LICENSE.md file in the package. 30 31 // [Guard] 32 #ifndef _ASMJIT_BASE_LOGGING_H 33 #define _ASMJIT_BASE_LOGGING_H 34 35 // [Dependencies] 36 #include "./inst.h" 37 #include "./moved_string.h" 38 39 // [Api-Begin] 40 #include "./asmjit_apibegin.h" 41 42 namespace PLMD { 43 namespace asmjit { 44 45 //! \addtogroup asmjit_base 46 //! \{ 47 48 #if !defined(ASMJIT_DISABLE_LOGGING) 49 50 // ============================================================================ 51 // [Forward Declarations] 52 // ============================================================================ 53 54 class CodeEmitter; 55 class Reg; 56 struct Operand_; 57 58 #if !defined(ASMJIT_DISABLE_BUILDER) 59 class CodeBuilder; 60 class CBNode; 61 #endif // !ASMJIT_DISABLE_BUILDER 62 63 // ============================================================================ 64 // [asmjit::Logger] 65 // ============================================================================ 66 67 //! Abstract logging interface and helpers. 68 //! 69 //! This class can be inherited and reimplemented to fit into your logging 70 //! subsystem. When reimplementing use `Logger::_log()` method to log into 71 //! a custom stream. 72 //! 73 //! There are two \ref Logger implementations offered by AsmJit: 74 //! - \ref FileLogger - allows to log into a `FILE*` stream. 75 //! - \ref StringLogger - logs into a \ref StringBuilder. 76 class ASMJIT_VIRTAPI Logger { 77 public: ASMJIT_NONCOPYABLE(Logger)78 ASMJIT_NONCOPYABLE(Logger) 79 80 // -------------------------------------------------------------------------- 81 // [Options] 82 // -------------------------------------------------------------------------- 83 84 //! Logger options. 85 ASMJIT_ENUM(Options) { 86 kOptionBinaryForm = 0x00000001, //! Output instructions also in binary form. 87 kOptionImmExtended = 0x00000002, //! Output a meaning of some immediates. 88 kOptionHexImmediate = 0x00000004, //! Output constants in hexadecimal form. 89 kOptionHexDisplacement = 0x00000008 //! Output displacements in hexadecimal form. 90 }; 91 92 // -------------------------------------------------------------------------- 93 // [Construction / Destruction] 94 // -------------------------------------------------------------------------- 95 96 //! Create a `Logger` instance. 97 ASMJIT_API Logger() noexcept; 98 //! Destroy the `Logger` instance. 99 ASMJIT_API virtual ~Logger() noexcept; 100 101 // -------------------------------------------------------------------------- 102 // [Logging] 103 // -------------------------------------------------------------------------- 104 105 //! Log `str` - must be reimplemented. 106 virtual Error _log(const char* str, size_t len) noexcept = 0; 107 108 //! Log a string `str`, which is either null terminated or having `len` length. 109 ASMJIT_INLINE Error log(const char* str, size_t len = Globals::kInvalidIndex) noexcept { return _log(str, len); } 110 //! Log a content of a `StringBuilder` `str`. log(const StringBuilder & str)111 ASMJIT_INLINE Error log(const StringBuilder& str) noexcept { return _log(str.getData(), str.getLength()); } 112 113 //! Format the message by using `sprintf()` and then send to `log()`. 114 ASMJIT_API Error logf(const char* fmt, ...) noexcept; 115 //! Format the message by using `vsprintf()` and then send to `log()`. 116 ASMJIT_API Error logv(const char* fmt, va_list ap) noexcept; 117 //! Log binary data. 118 ASMJIT_API Error logBinary(const void* data, size_t size) noexcept; 119 120 // -------------------------------------------------------------------------- 121 // [Options] 122 // -------------------------------------------------------------------------- 123 124 //! Get all logger options as a single integer. getOptions()125 ASMJIT_INLINE uint32_t getOptions() const noexcept { return _options; } 126 //! Get the given logger option. hasOption(uint32_t option)127 ASMJIT_INLINE bool hasOption(uint32_t option) const noexcept { return (_options & option) != 0; } addOptions(uint32_t options)128 ASMJIT_INLINE void addOptions(uint32_t options) noexcept { _options |= options; } clearOptions(uint32_t options)129 ASMJIT_INLINE void clearOptions(uint32_t options) noexcept { _options &= ~options; } 130 131 // -------------------------------------------------------------------------- 132 // [Indentation] 133 // -------------------------------------------------------------------------- 134 135 //! Get indentation. getIndentation()136 ASMJIT_INLINE const char* getIndentation() const noexcept { return _indentation; } 137 //! Set indentation. 138 ASMJIT_API void setIndentation(const char* indentation) noexcept; 139 //! Reset indentation. resetIndentation()140 ASMJIT_INLINE void resetIndentation() noexcept { setIndentation(nullptr); } 141 142 // -------------------------------------------------------------------------- 143 // [Members] 144 // -------------------------------------------------------------------------- 145 146 //! Options, see \ref LoggerOption. 147 uint32_t _options; 148 149 //! Indentation. 150 char _indentation[12]; 151 }; 152 153 // ============================================================================ 154 // [asmjit::FileLogger] 155 // ============================================================================ 156 157 //! Logger that can log to a `FILE*` stream. 158 class ASMJIT_VIRTAPI FileLogger : public Logger { 159 public: 160 ASMJIT_NONCOPYABLE(FileLogger) 161 162 // -------------------------------------------------------------------------- 163 // [Construction / Destruction] 164 // -------------------------------------------------------------------------- 165 166 //! Create a new `FileLogger` that logs to a `FILE` stream. 167 ASMJIT_API FileLogger(FILE* stream = nullptr) noexcept; 168 //! Destroy the `FileLogger`. 169 ASMJIT_API virtual ~FileLogger() noexcept; 170 171 // -------------------------------------------------------------------------- 172 // [Accessors] 173 // -------------------------------------------------------------------------- 174 175 //! Get the logging out put stream or null. getStream()176 ASMJIT_INLINE FILE* getStream() const noexcept { return _stream; } 177 178 //! Set the logging output stream to `stream` or null. 179 //! 180 //! NOTE: If the `stream` is null it will disable logging, but it won't 181 //! stop calling `log()` unless the logger is detached from the 182 //! \ref Assembler. setStream(FILE * stream)183 ASMJIT_INLINE void setStream(FILE* stream) noexcept { _stream = stream; } 184 185 // -------------------------------------------------------------------------- 186 // [Logging] 187 // -------------------------------------------------------------------------- 188 189 ASMJIT_API Error _log(const char* buf, size_t len = Globals::kInvalidIndex) noexcept override; 190 191 // -------------------------------------------------------------------------- 192 // [Members] 193 // -------------------------------------------------------------------------- 194 195 //! C file stream. 196 FILE* _stream; 197 }; 198 199 // ============================================================================ 200 // [asmjit::StringLogger] 201 // ============================================================================ 202 203 //! Logger that stores everything in an internal string buffer. 204 class ASMJIT_VIRTAPI StringLogger : public Logger { 205 public: 206 ASMJIT_NONCOPYABLE(StringLogger) 207 208 // -------------------------------------------------------------------------- 209 // [Construction / Destruction] 210 // -------------------------------------------------------------------------- 211 212 //! Create new `StringLogger`. 213 ASMJIT_API StringLogger() noexcept; 214 //! Destroy the `StringLogger`. 215 ASMJIT_API virtual ~StringLogger() noexcept; 216 217 // -------------------------------------------------------------------------- 218 // [Accessors] 219 // -------------------------------------------------------------------------- 220 221 //! Get `char*` pointer which represents the resulting string. 222 //! 223 //! The pointer is owned by `StringLogger`, it can't be modified or freed. getString()224 ASMJIT_INLINE const char* getString() const noexcept { return _stringBuilder.getData(); } 225 //! Clear the resulting string. clearString()226 ASMJIT_INLINE void clearString() noexcept { _stringBuilder.clear(); } 227 228 //! Get the length of the string returned by `getString()`. getLength()229 ASMJIT_INLINE size_t getLength() const noexcept { return _stringBuilder.getLength(); } 230 231 // -------------------------------------------------------------------------- 232 // [Logging] 233 // -------------------------------------------------------------------------- 234 235 ASMJIT_API Error _log(const char* buf, size_t len = Globals::kInvalidIndex) noexcept override; 236 237 // -------------------------------------------------------------------------- 238 // [Members] 239 // -------------------------------------------------------------------------- 240 241 //! Output string. 242 StringBuilder _stringBuilder; 243 }; 244 245 // ============================================================================ 246 // [asmjit::Logging] 247 // ============================================================================ 248 249 struct Logging { 250 ASMJIT_API static Error formatRegister( 251 StringBuilder& sb, 252 uint32_t logOptions, 253 const CodeEmitter* emitter, 254 uint32_t archType, 255 uint32_t regType, 256 uint32_t regId) noexcept; 257 258 ASMJIT_API static Error formatLabel( 259 StringBuilder& sb, 260 uint32_t logOptions, 261 const CodeEmitter* emitter, 262 uint32_t labelId) noexcept; 263 264 ASMJIT_API static Error formatOperand( 265 StringBuilder& sb, 266 uint32_t logOptions, 267 const CodeEmitter* emitter, 268 uint32_t archType, 269 const Operand_& op) noexcept; 270 271 ASMJIT_API static Error formatInstruction( 272 StringBuilder& sb, 273 uint32_t logOptions, 274 const CodeEmitter* emitter, 275 uint32_t archType, 276 const Inst::Detail& detail, const Operand_* opArray, uint32_t opCount) noexcept; 277 278 #if !defined(ASMJIT_DISABLE_BUILDER) 279 ASMJIT_API static Error formatNode( 280 StringBuilder& sb, 281 uint32_t logOptions, 282 const CodeBuilder* cb, 283 const CBNode* node_) noexcept; 284 #endif // !ASMJIT_DISABLE_BUILDER 285 286 // Only used by AsmJit internals, not available to users. 287 #if defined(ASMJIT_EXPORTS) 288 enum { 289 // Has to be big to be able to hold all metadata compiler can assign to a 290 // single instruction. 291 kMaxCommentLength = 512, 292 kMaxInstLength = 40, 293 kMaxBinaryLength = 26 294 }; 295 296 static Error formatLine( 297 StringBuilder& sb, 298 const uint8_t* binData, size_t binLen, size_t dispLen, size_t imLen, const char* comment) noexcept; 299 #endif // ASMJIT_EXPORTS 300 }; 301 #else 302 class Logger; 303 #endif // !ASMJIT_DISABLE_LOGGING 304 305 //! \} 306 307 } // asmjit namespace 308 } // namespace PLMD 309 310 // [Api-End] 311 #include "./asmjit_apiend.h" 312 313 // [Guard] 314 #endif // _ASMJIT_BASE_LOGGER_H 315 #pragma GCC diagnostic pop 316 #endif // __PLUMED_HAS_ASMJIT 317 #endif 318