1 /*========================== begin_copyright_notice ============================ 2 3 Copyright (C) 2017-2021 Intel Corporation 4 5 SPDX-License-Identifier: MIT 6 7 ============================= end_copyright_notice ===========================*/ 8 9 /* 10 * The IGA - Intel Gen Assembler external C API 11 */ 12 #ifndef IGA_H 13 #define IGA_H 14 15 #include "iga_types_swsb.hpp" 16 17 #include <stdint.h> 18 #include <stddef.h> 19 #ifdef _WIN32 20 #include <crtdefs.h> 21 #endif 22 23 #ifdef _WIN32 24 #ifdef IGA_BUILDING_DLL 25 #define IGA_API __declspec(dllexport) 26 /* define this symbol if you wish to statically link against iga32.dll */ 27 #elif IGA_DLL_IMPORT 28 #define IGA_API __declspec(dllimport) 29 #else 30 #define IGA_API 31 #endif 32 #else 33 #if __GNUC__ >= 4 34 #define IGA_API __attribute__ ((visibility ("default"))) 35 #else 36 #define IGA_API 37 #endif 38 #endif 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 /* opaque pointer to context type */ 45 typedef void *iga_context_t; 46 47 typedef enum { 48 IGA_SUCCESS = 0, /* the operation completed successfully 49 * (iga_disassemble and iga_assemble may 50 * still have logged warnings) */ 51 IGA_ERROR = 1, /* general error */ 52 IGA_INVALID_ARG = 2, /* something wrong with an arugment */ 53 IGA_OUT_OF_MEM = 3, /* failed to allocate */ 54 IGA_DECODE_ERROR = 4, /* error during decode phase */ 55 IGA_ENCODE_ERROR = 5, /* error during the encode phase */ 56 IGA_PARSE_ERROR = 6, /* error duing the parse phase (syntax) */ 57 IGA_VERSION_ERROR = 7, /* this header file is newer than the binary 58 * called */ 59 IGA_INVALID_OBJECT = 8, /* attempt to use an destroyed object 60 * (e.g. iga_context_t) */ 61 IGA_INVALID_STATE = 9, /* e.g. call to iga_get_errors before disassembly*/ 62 IGA_UNSUPPORTED_PLATFORM = 10, /* platform not supported with this binary */ 63 IGA_DIFF_FAILURE = 11 /* used by -Xifs for diffing instructions */ 64 } iga_status_t; 65 66 /* 67 * Converts an IGA status string code to a human-readable string. 68 * 69 * RETURNS: IGA_SUCCESS 70 */ 71 IGA_API const char *iga_status_to_string(iga_status_t st); 72 73 74 /* 75 * Returns a NUL-terminated version string corresponding to the version of 76 * IGA. 77 */ 78 IGA_API const char *iga_version_string(); 79 80 81 /* The encoding for GEN version enumerates follows this pattern */ 82 #define GEN_VER(MAJ,MIN) (((MAJ)<<16)|(MIN)) 83 84 /* The encoding for XE version enumerates follows this pattern 85 * All XE_VER() must be larger than GEN_VER(). XE_VER(0,*) is illegal. TGL is XE_VER(1,0) 86 */ 87 #define XE_VER(MAJ,MIN) (((MAJ)<<24)|(MIN)) 88 89 90 /* Represents the specific version of Gen being assembled or disassembled */ 91 typedef enum { 92 IGA_GEN_INVALID = 0 93 , IGA_GEN7 = GEN_VER(7,0) 94 , IGA_GEN7p5 = GEN_VER(7,5) 95 , IGA_GEN8 = GEN_VER(8,0) 96 , IGA_GEN8lp = GEN_VER(8,1) 97 , IGA_GEN9 = GEN_VER(9,0) 98 , IGA_GEN9lp = GEN_VER(9,1) 99 , IGA_GEN9p5 = GEN_VER(9,5) 100 , IGA_GEN10 = GEN_VER(10,0) 101 , IGA_GEN11 = GEN_VER(11,0) 102 // XE versions 103 , IGA_XE = XE_VER(1, 0) // TGL 104 , IGA_XE_HP = XE_VER(1, 1) 105 , IGA_XE_HPG = XE_VER(1, 2) 106 , IGA_XE_HPC = XE_VER(1, 4) 107 108 // TO BE DEPRECATED 109 // Preserve the old values to maintain the binary compatibility 110 // The value should not be used anymore 111 , IGA_GEN12p1 = GEN_VER(12,1) // IGA_XE 112 } iga_gen_t; 113 114 115 /*****************************************************************************/ 116 /* Platform Query Functions */ 117 /*****************************************************************************/ 118 119 /* 120 * Returns a list of the platforms enumeration values supported by this 121 * implementation of IGA into a user-provided buffer. The buffer parameter 122 * maybe omitted. 123 * 124 * PARAMETERS: 125 * gens_length_bytes the length of the gens buffer in bytes; 126 * can be 0 if gens is NULL 127 * gens the user-provided buffer (can be NULL); 128 * if non-NULL, the output will contain the list 129 * of iga_gen_t platforms that this IGA supports 130 * gens_length_bytes_required the required length 131 * 132 * RETURNS: 133 * IGA_INVALID_ARGUMENT if gens_length_bytes != 0 && gens == nullptr 134 * IGA_SUCCESS otherwise 135 */ 136 IGA_API iga_status_t iga_platforms_list( 137 size_t gens_length_bytes, 138 iga_gen_t *gens, 139 size_t *gens_length_bytes_required); 140 /* 141 * Returns the platform suffix name of a given platform. 142 * 143 * PARAMETERS: 144 * gen the platform to query 145 * suffix an output parameter assigned the result; 146 * NULL is assigned if the 'gen' passed in is invalid 147 * or unsupported 148 * 149 * RETURNS: 150 * IGA_INVALID_ARGUMENT if symbol is NULL or 'gen' is invalid or not 151 * supported by this platform 152 * IGA_SUCCESS otherwise 153 */ 154 IGA_API iga_status_t iga_platform_symbol_suffix( 155 iga_gen_t gen, 156 const char **suffix); 157 /* 158 * Returns the names for a given platform. E.g. IGA_GEN9 returns "skl". 159 * 160 * PARAMETERS: 161 * gen the platform to query 162 * names_bytes the length in bytes of the names array passed in 163 * 0 iff 'names' is nullptr 164 * names the array to return the platform names in 165 * names_bytes_needed the required length of 'names' in bytes 166 * 167 * RETURNS: 168 * IGA_INVALID_ARGUMENT if gen is an invalid platform 169 * supported by this platform 170 * IGA_INVALID_ARGUMENT if names_bytes != 0 && names == nullptr 171 * IGA_SUCCESS otherwise 172 */ 173 IGA_API iga_status_t iga_platform_names( 174 iga_gen_t gen, 175 size_t names_bytes, 176 const char **names, 177 size_t *names_bytes_needed); 178 179 180 181 /*****************************************************************************/ 182 /* Context Creation Functions */ 183 /*****************************************************************************/ 184 185 /* 186 * Context options 187 */ 188 typedef struct { 189 size_t cb; /* set to sizeof(iga_context_options_t) */ 190 iga_gen_t gen; 191 } iga_context_options_t; 192 /* this is an ugly wart, cb should have been uint32_t * 193 * TODO: change this in IGA 2.0 and break binary compatibility there*/ 194 195 /* 196 * This macro initializes options to the context. 197 * iga_gen_t P the gen platform to use 198 */ 199 #define IGA_CONTEXT_OPTIONS_INIT(P) \ 200 {sizeof(iga_context_options_t), (P)} 201 202 203 /* 204 * Creates a context, which is needed to assemble and disassemble kernels. 205 * A context manages internal dynamically allocated memory containing 206 * the diagnostics. 207 * 208 * PARAMETERS: 209 * opts the options to this iga context 210 * ctx points to the newly created context 211 * 212 * RETURNS: 213 * IGA_SUCCESS upon successful context creation 214 * IGA_INVALID_ARG if an argument is NULL 215 * IGA_INVALID_OBJECT if ctx has already been destroyed 216 * IGA_OUT_OF_MEM upon internal allocation failure 217 * IGA_INVALID_PLATFORM if the platform passed is unsupported 218 */ 219 IGA_API iga_status_t iga_context_create( 220 const iga_context_options_t *opts, 221 iga_context_t *ctx); 222 /* deprecated: covers to iga_context_create */ 223 IGA_API iga_status_t iga_create_context( 224 const iga_context_options_t *opts, 225 iga_context_t *ctx); 226 227 228 /* 229 * Releases a context previously created via 'iga_context_create'. 230 * 231 * RETURNS: 232 * IGA_SUCCESS upon successful context release 233 * IGA_INVALID_ARG if an argument is NULL 234 * IGA_INVALID_OBJECT if ctx has already been destroyed 235 */ 236 IGA_API iga_status_t iga_context_release(iga_context_t ctx); 237 /* deprecated: covers to iga_context_release */ 238 IGA_API iga_status_t iga_release_context(iga_context_t ctx); 239 240 241 /*****************************************************************************/ 242 /* Assembly Functions */ 243 /*****************************************************************************/ 244 245 /* 246 * This structure contains options to the 'iga_assemble' call. 247 */ 248 typedef struct { 249 uint32_t cb; /* sizeof(iga_context_options_t) */ 250 uint32_t enabled_warnings; /* bitset of IGA_WARNINGS* */ 251 uint32_t encoder_opts; /* bitset of IGA_ENCODER_OPT* */ 252 uint32_t syntax_opts; /* bitset of IGA_SYNTAX_OPT* */ 253 /* the following must be 0 or a warning is raised */ 254 uint32_t _reserved0; /* use IGA_ENCODER_OPT_ERRONCOMPACT */ 255 uint32_t _reserved1; /* use IGA_ENCODER_OPT_AUTODEP */ 256 /* 257 * ... future fields (ensure total size is a multiple of 8; 258 * add "reserved" if needed) ... 259 * do not reuse _reserved0 and _reserved1 since those were 260 * historically something else 261 */ 262 263 // number of sbid used for auto dependency setting. This value is effective 264 // only when IGA_ENCODER_OPT_AUTO_DEPENDENCIES is given 265 uint32_t sbid_count; 266 // force the swsb_encode_mode. If not given, the encode mode will be 267 // derived from platform 268 iga::SWSB_ENCODE_MODE swsb_encode_mode; 269 } iga_assemble_options_t; 270 271 /* detects screwups where someone adds a field and the compiler pads 272 * the structure out implicitly */ 273 static_assert(sizeof(iga_assemble_options_t) == 8*4, 274 "wrong size for iga_assemble_options"); 275 276 277 /* 278 * encoding options 279 */ 280 /* 281 * Automatically compact instructions without explicit compaction annotations. 282 * E.g. with this enabled: 283 * op (...) ... {Compacted} // will compact 284 * op (...) ... { } // try and compact iff IGA_ENCOPTS_AUTOCOMPACT 285 * op (...) ... {Uncompacted} // will not attempt to compact 286 */ 287 #define IGA_ENCODER_OPT_AUTO_COMPACT 0x00000001u 288 /* auto set instruction dependencies */ 289 #define IGA_ENCODER_OPT_AUTO_DEPENDENCIES 0x00000002u 290 /* treat failure to compact an instruction with a {Compacted} annotation 291 * as a hard error rather than just raising a warning */ 292 #define IGA_ENCODER_OPT_ERROR_ON_COMPACT_FAIL 0x00000004u 293 /* enable experimental native encoder */ 294 #define IGA_ENCODER_OPT_USE_NATIVE 0x00000008u 295 /* forcely NoCompact to all instructions even if {Compacted} is set on the instruction 296 This option will overried IGA_ENCODER_OPT_AUTO_COMPACT */ 297 #define IGA_ENCODER_OPT_FORCE_NO_COMPACT 0x00000010u 298 299 /* 300 * options for the parsing phase 301 */ 302 /* nominal support for certain IsaAsm directives and syntax */ 303 #define IGA_SYNTAX_OPT_LEGACY_SYNTAX 0x00000001u 304 /* enables syntax extensions */ 305 #define IGA_SYNTAX_OPT_EXTENSIONS 0x00000002u 306 307 308 /* 309 * extra assemble warnings (things to check) 310 * (for iga_assemble_options_t::enabled_warnings) 311 */ 312 /* individual warnings */ 313 #define IGA_WARNINGS_REGIONS 0x00000001u /* -Wregions */ 314 #define IGA_WARNINGS_TYPES 0x00000002u /* -Wtypes */ 315 #define IGA_WARNINGS_SCHED 0x00000004u /* -Wscheduling */ 316 #define IGA_WARNINGS_NORMFORM 0x00000008u /* -Wnormal-form */ 317 /* useful predefined sets */ 318 #define IGA_WARNINGS_NONE 0x00000000u /* -Wnone */ 319 #define IGA_WARNINGS_ALL \ 320 (IGA_WARNINGS_REGIONS|\ 321 IGA_WARNINGS_TYPES|\ 322 IGA_WARNINGS_SCHED|\ 323 IGA_WARNINGS_NORMFORM) /* -Wall */ 324 #define IGA_WARNINGS_DEFAULT \ 325 (IGA_WARNINGS_REGIONS|\ 326 IGA_WARNINGS_SCHED) /* -Wdefault */ 327 328 /* helpful initializers for assembly options with good defaults */ 329 #define IGA_ASSEMBLE_OPTIONS_INIT() \ 330 { \ 331 sizeof(iga_assemble_options_t), \ 332 IGA_WARNINGS_DEFAULT, \ 333 (IGA_ENCODER_OPT_ERROR_ON_COMPACT_FAIL), \ 334 0, /* syntax_opts = NONE */ \ 335 0, /* reserved */ \ 336 0, /* reserved */ \ 337 16, /* sbid_count */ \ 338 iga::SWSB_ENCODE_MODE::SWSBInvalidMode \ 339 } 340 341 /* 342 * Assembles some text into bits. 343 * 344 * PARAMETERS: 345 * ctx the iga context 346 * opts the assemble options 347 * kernel_text a NUL-terminated string containing the kernel text 348 * to assemble 349 * output the output assembly binary; upon failure, this is 350 * assigned NULL; this memory should not be modified 351 * or deallocated externally 352 * output_size the length of 'output' (in bytes); assigned 0 upon failure 353 * 354 * RETURNS: 355 * IGA_SUCCESS upon successful assembly; 'iga_get_warnings' may 356 * contain warning diagnostics even upon success 357 * IGA_INVALID_ARG if an argument is NULL 358 * IGA_INVALID_OBJECT if ctx has already been destroyed 359 * IGA_PARSE_ERROR if the text is somehow malformed and IGA is unable 360 * to parse it; use iga_get_errors for more info 361 * IGA_ENCODE_ERROR if the encoder encounters some error 362 * (use iga_get_errors for more info) 363 * IGA_ERROR upon some other error 364 */ 365 IGA_API iga_status_t iga_context_assemble( 366 iga_context_t ctx, 367 const iga_assemble_options_t *opts, 368 const char *kernel_text, 369 void **output, 370 uint32_t *output_size); 371 /* deprecated API covers to iga_contex* */ 372 IGA_API iga_status_t iga_assemble( 373 iga_context_t ctx, 374 const iga_assemble_options_t *opts, 375 const char *kernel_text, 376 void **output, 377 uint32_t *output_size); 378 379 380 /*****************************************************************************/ 381 /* Disassembly Functions */ 382 /*****************************************************************************/ 383 384 /* 385 * This structure contains options to the 'iga_disassemble' call. 386 */ 387 typedef struct { 388 uint32_t cb; /* set to sizeof(iga_context_options_t) */ 389 uint32_t formatting_opts; /* options in formatting the syntax */ 390 uint32_t _reserved0; /* use formatting_opts; set this to 0! */ 391 uint32_t _reserved1; /* use formatting_opts; set this to 0! */ 392 uint32_t decoder_opts; /* opts for the decoding phase */ 393 /* ... future fields (ensure total size is a multiple of 8; 394 * add "reserved" if needed) ... */ 395 } iga_disassemble_options_t; 396 397 static_assert(sizeof(iga_disassemble_options_t) == 5*4, 398 "wrong size for iga_disassemble_options_t"); 399 400 /* A default value for iga_disassemble_options_t */ 401 #define IGA_DISASSEMBLE_OPTIONS_INIT() \ 402 {sizeof(iga_disassemble_options_t), \ 403 IGA_FORMATTING_OPTS_DEFAULT, \ 404 0, /* _reserved0 */ \ 405 0, /* _reserved1 */ \ 406 IGA_DECODING_OPTS_DEFAULT, /* decoder_opts */ } 407 408 /* A default value for iga_disassemble_options_t that enables numeric labels */ 409 #define IGA_DISASSEMBLE_OPTIONS_INIT_NUMERIC_LABELS() \ 410 {sizeof(iga_disassemble_options_t), \ 411 IGA_FORMATTING_OPTS_DEFAULT|IGA_FORMATTING_OPT_NUMERIC_LABELS, \ 412 0, /* _reserved0 */ \ 413 0, /* _reserved1 */ \ 414 IGA_DECODING_OPTS_DEFAULT, /* decoder_opts */ } 415 416 /* 417 * options for the formatting phase (the syntax emitted / printed) 418 */ 419 /* does not use numeric labels */ 420 #define IGA_FORMATTING_OPT_NUMERIC_LABELS 0x00000001u 421 /* enables certain syntax extensions */ 422 #define IGA_FORMATTING_OPT_SYNTAX_EXTS 0x00000002u 423 /* force floats to be emitted in hexadecimal */ 424 #define IGA_FORMATTING_OPT_PRINT_HEX_FLOATS 0x00000004u 425 /* print the instruction PC's */ 426 #define IGA_FORMATTING_OPT_PRINT_PC 0x00000008u 427 /* print the instruction bits */ 428 #define IGA_FORMATTING_OPT_PRINT_BITS 0x00000010u 429 /* print immediate instruction dependencies (mostly for IGA debugging) */ 430 #define IGA_FORMATTING_OPT_PRINT_DEPS 0x00000020u 431 /* print load/store pseduo instructions where possible */ 432 #define IGA_FORMATTING_OPT_PRINT_LDST 0x00000040u 433 /* print bfn symbolic instructions */ 434 #define IGA_FORMATTING_OPT_PRINT_BFNEXPRS 0x00000080u 435 /* use ansi_span escapes when possible */ 436 #define IGA_FORMATTING_OPT_PRINT_ANSI 0x00000100u 437 /* emit JSON instead of asm */ 438 #define IGA_FORMATTING_OPT_PRINT_JSON 0x00000200u 439 /* emit instruction definitions from a simple dataflow analysis */ 440 #define IGA_FORMATTING_OPT_PRINT_DEFS 0x00000400u 441 442 /* just the default formatting opts */ 443 #define IGA_FORMATTING_OPTS_DEFAULT \ 444 (0u) 445 /* a union of all formatter opts */ 446 #define IGA_FORMATTING_OPTS_ALL = \ 447 (IGA_FORMATTING_OPT_NUMERIC_LABELS\ 448 |IGA_FORMATTING_OPT_SYNTAX_EXTS\ 449 |IGA_FORMATTING_OPT_PRINT_HEX_FLOATS\ 450 |IGA_FORMATTING_OPT_PRINT_PC\ 451 |IGA_FORMATTING_OPT_PRINT_BITS\ 452 |IGA_FORMATTING_OPT_PRINT_DEPS\ 453 |IGA_FORMATTING_OPT_PRINT_DEFS) 454 455 /* uses the native decoder for decoding the kernel */ 456 #define IGA_DECODING_OPT_NATIVE 0x00000001u 457 /* just the default decoding opts */ 458 #define IGA_DECODING_OPTS_DEFAULT \ 459 (0u) 460 461 /* 462 * Disassembles kernel bits into a string. 463 * 464 * PARAMETERS: 465 * ctx an iga context 466 * dopts the disassemble options 467 * input the instructions to disassemble 468 * input_size the size of the 'input' in bytes 469 * fmt_label_name optional callback to resolve a PC to specific label 470 * - if the callback is NULL or the callback returns NULL, 471 * then IGA generates the label names 472 * - for instructions with multiple labels the caller 473 * may reuse any buffers for each label 474 * *** PCs are relative to the start of the disassembly *** 475 * *** for this API *** 476 * fmt_label_ctx A callback context (environment) forwarded to 'fmt_label' 477 * E.g. a buffer to construct the label with 478 * kernel_text a pointer containing the NUL-terminate disassembly text; 479 * this memory is internally allocated and should not be freed 480 * by the user; moreover, it may be invalidated upon the next 481 * call using this context (freed or even reused); upon a 482 * decoding error this may contain the partially decoded 483 * kernel or the empty string if something catestrophic 484 * happened, but the pointer returned will always be valid 485 * (until the subsequent call) 486 * 487 * RETURNS: 488 * IGA_SUCCESS upon successful disassembly; 'iga_get_warnings' may 489 * contain warning diagnostics even upon success 490 * IGA_INVALID_ARG if an argument is NULL; 'input' may be NULL only 491 * if 'input_size' is also 0 492 * IGA_INVALID_OBJECT if ctx has already been destroyed 493 * IGA_DECODE_ERROR upon failure to decode error; specific error messages 494 * may be retrieved via 'iga_context_get_errors' 495 */ 496 IGA_API iga_status_t iga_context_disassemble( 497 iga_context_t ctx, 498 const iga_disassemble_options_t *opts, 499 const void *input, 500 uint32_t input_size, 501 const char *(*fmt_label_name)(int32_t, void *), 502 void *fmt_label_ctx, 503 char **kernel_text); 504 /* deprecated API covers to iga_context_* */ 505 IGA_API iga_status_t iga_disassemble( 506 iga_context_t ctx, 507 const iga_disassemble_options_t *opts, 508 const void *input, 509 uint32_t input_size, 510 const char *(*fmt_label_name)(int32_t, void *), 511 void *fmt_label_ctx, 512 char **kernel_text); 513 514 515 /* 516 * Disassembles a single instruction. 517 * 518 * ctx an iga context 519 * dopts the disassemble options 520 * input the instructions to disassemble; the first 8-16 bytes 521 * must be readable (16 if compaction control is set) 522 * fmt_label_name optional callback to resolve a PC to specific label 523 * - if the callback is NULL or the callback returns NULL, 524 * then IGA generates the label names 525 * - for instructions with multiple labels the caller 526 * may reuse any buffers for each label 527 * *** PCs are relative to the start of this instruction *** 528 * *** for this API *** 529 * fmt_label_ctx A callback context (environment) forwarded to 'fmt_label' 530 * E.g. a buffer to construct the label with 531 * kernel_text a pointer containing the NUL-terminate disassembly text; 532 * this memory is internally allocated and should not be freed 533 * by the user; moreover, it may be invalidated upon the next 534 * call using this context (freed or even reused); upon a 535 * decoding error this may contain the partially decoded 536 * kernel or the empty string if something catestrophic 537 * happened, but the pointer returned will always be valid 538 * (until the subsequent call) 539 * 540 * RETURNS: 541 * IGA_SUCCESS upon successful disassembly; 'iga_get_warnings' may 542 * contain warning diagnostics even upon success 543 * IGA_INVALID_ARG if an argument is NULL 544 * IGA_INVALID_OBJECT if ctx has already been destroyed 545 * IGA_DECODE_ERROR upon failure to decode error; specific error messages 546 * may be retrieved via 'iga_context_get_errors' 547 */ 548 IGA_API iga_status_t iga_context_disassemble_instruction( 549 iga_context_t ctx, 550 const iga_disassemble_options_t *dopts, 551 const void *input, 552 const char *(*fmt_label_name)(int32_t, void *), 553 void *fmt_label_ctx, 554 char **kernel_text); 555 /* deprecated API covers to iga_contex* */ 556 IGA_API iga_status_t iga_disassemble_instruction( 557 iga_context_t ctx, 558 const iga_disassemble_options_t *dopts, 559 const void *input, 560 const char *(*fmt_label_name)(int32_t, void *), 561 void *fmt_label_ctx, 562 char **kernel_text); 563 564 565 /*****************************************************************************/ 566 /* Diagnostic Processing Functions */ 567 /*****************************************************************************/ 568 569 /* 570 * A diagnostic message (e.g. error or warning) 571 * 572 * WARNING: This structure may be made opaque in future releases. 573 * Treat it as an opaque type and use the accessors to minimize 574 * any conversion time down the road. 575 */ 576 typedef struct { 577 /* lines start at 1; 0 means no location information */ 578 uint32_t line; 579 /* columns start at 1; 0 means no location information */ 580 uint32_t column; 581 /* the input offset */ 582 uint32_t offset; 583 /* the length of the diagnostic (in characters) */ 584 uint32_t extent; 585 /* the diagnostic message (NUL terminated) */ 586 const char *message; 587 } iga_diagnostic_t; 588 589 590 /* 591 * Gets the errors from previous 'iga_context_assemble' or 592 * 'iga_context_disassmble'. It is an error to call this before one of these 593 * functions have been called. Further invocations of this function return 594 * the same values until one of the above functions is called again. Memory 595 * returned by this function should not be modified externally. Moreover, it 596 * should not be accessed after the next call to 'iga_context_assemble' or 597 * 'iga_context_disassmble' or the call to 'iga_context_release'. 598 * 599 * PARAMETERS: 600 * ctx the iga context used in the call to 'iga_context_assemble' 601 * or 'iga_context_disassmble' 602 * ds assigned to an internally allocated array of diagnostic 603 * messages (the caller should *not* mutate or free this memory) 604 * ds_len assigned the length of 'ds' upon success 605 * 606 * RETURNS: 607 * IGA_SUCCESS upon getting the list of errors; note if the last call 608 * contained no errors, this still returns IGA_SUCCESS; 609 * 'ds' is assigned a NULL pointer and 'ds_len' is assigned 0. 610 * IGA_INVALID_ARG if an argument is NULL 611 * IGA_INVALID_OBJECT if ctx has already been destroyed 612 * IGA_ERROR if 'iga_assemble' or 'iga_disassmble' never called, 613 * internal allocation fails, or the context is invalid 614 * (after call to 'iga_context_release'). 615 */ 616 IGA_API iga_status_t iga_context_get_errors( 617 iga_context_t ctx, 618 const iga_diagnostic_t **ds, 619 uint32_t *ds_len); 620 IGA_API iga_status_t iga_get_errors( 621 iga_context_t ctx, 622 const iga_diagnostic_t **ds, 623 uint32_t *ds_len); 624 625 626 /* 627 * Symmetric to 'iga_context_get_errors'. Various API calls can still succeed 628 * even if there are warnings; hence, robust tools should always check this 629 * as well. 630 */ 631 IGA_API iga_status_t iga_context_get_warnings( 632 iga_context_t ctx, 633 const iga_diagnostic_t **ds, 634 uint32_t *ds_len); 635 IGA_API iga_status_t iga_get_warnings( 636 iga_context_t ctx, 637 const iga_diagnostic_t **ds, 638 uint32_t *ds_len); 639 640 641 /* 642 * Fetches a diagnostic's message. The internal memory containing the message 643 * should be copied out before further disassemble or assembly or context 644 * destruction. This diagnostic field is valid for both binary and text. 645 * 646 * RETURNS: 647 * IGA_SUCCESS upon success 648 * IGA_INVALID_ARG if an argument is NULL 649 */ 650 IGA_API iga_status_t iga_diagnostic_get_message( 651 const iga_diagnostic_t *d, 652 const char **message); 653 654 655 /* 656 * Returns the starting file offset for the diagnostic in bytes (zero based). 657 * This diagnostic field is valid for both binary and text. 658 * 659 * RETURNS: 660 * IGA_SUCCESS upon success 661 * IGA_INVALID_ARG if an argument is NULL or the diagnostic is a binary 662 * location 663 */ 664 IGA_API iga_status_t iga_diagnostic_get_offset( 665 const iga_diagnostic_t *d, 666 uint32_t *offset); 667 668 669 /* 670 * Diagnostics can refer to locations in binary files or text files. 671 * The following enumeration indicates which. 672 */ 673 typedef enum { 674 /* the location refers to a text location */ 675 IGA_DIAGNOSTIC_TEXT, 676 /* the location refers to a binary location */ 677 IGA_DIAGNOSTIC_BINARY, 678 } iga_diagnostic_type_t; 679 680 681 /* 682 * Fetches the type of diagnostic (binary or text). 683 * For IGA_DIAGNOSTIC_TEXT iga_diagnostic_text_get_* should be used to access 684 * further information. 685 * For IGA_DIAGNOSTIC_BINARY 'iga_diagnostic_get_offset* should be used 686 * access more the binary offset 687 * 688 * RETURNS: 689 * IGA_SUCCESS upon success 690 * IGA_INVALID_ARG if an argument is NULL or the diagnostic is a binary 691 * location 692 */ 693 IGA_API iga_status_t iga_diagnostic_get_type( 694 const iga_diagnostic_t *d, 695 iga_diagnostic_type_t *dt); 696 697 698 /* 699 * Fetches a diagnostic's line number (must be IGA_DIAGNOSTIC_TEXT). 700 * Lines numbers are counted from 1. 701 * 702 * RETURNS: 703 * IGA_SUCCESS upon success 704 * IGA_INVALID_ARG if an argument is NULL or the diagnostic is a binary 705 * location 706 */ 707 IGA_API iga_status_t iga_diagnostic_get_text_line( 708 const iga_diagnostic_t *d, 709 uint32_t *line); 710 711 712 /* 713 * Similar to 'iga_diagnostic_text_get_line', but returns the column. 714 * Columns are counted from 1. 715 */ 716 IGA_API iga_status_t iga_diagnostic_get_text_column( 717 const iga_diagnostic_t *d, 718 uint32_t *col); 719 720 721 /* 722 * Fetches a binary diagnostic's byte offset (must be IGA_DIAGNOSTIC_TEXT). 723 * The extent is the length of the region of source code. 724 * 725 * RETURNS: 726 * IGA_SUCCESS upon success 727 * IGA_INVALID_ARG if an argument is NULL or the diagnostic is a binary 728 * location 729 */ 730 IGA_API iga_status_t iga_diagnostic_get_text_extent( 731 const iga_diagnostic_t *d, 732 uint32_t *extent); 733 734 735 736 /*****************************************************************************/ 737 /* Operation Enumeration Functions */ 738 /*****************************************************************************/ 739 /* 740 * An opaque type representing an operation (instruction) type. 741 * Can be efficiently copied and passed by value. 742 */ 743 typedef const struct opspec* iga_opspec_t; 744 745 /* 746 * Enumerates the opcodes for a given platform. 747 * 'gen' : gen plaform to enumerate operations on 748 * 'ops_arr' : a pointer (can be nul) to an array to hold 749 * all opcode spec. 750 * 'ops_arr_len' : the required length for 'ops_arr' 751 * This API is the usual two-shot pattern, in which the caller invokes it 752 * first time to get the length, the caller allocates enough space to hold 753 * info based on the returned length, then the caller invokes it again. 754 * 755 * This function always returns the required length of the array 756 * from argument 'ops_arr_len'. 757 * 758 * For example, 759 * size_t len; 760 * iga_opspec_enumerate(gen, nullptr, &len); 761 * iga_opspec_t *ops_arr = 762 * (iga_opspec_t*)malloc(sizeof(iga_opspec_t) * len); 763 * iga_opspec_enumerate(gen, ops_arr, &len); 764 * 765 * RETURNS: 766 * IGA_SUCCESS upon success 767 * IGA_INVALID_ARG if a gen argument invalid or ops_arr_len is null 768 */ 769 IGA_API iga_status_t iga_opspec_enumerate( 770 iga_gen_t gen, 771 iga_opspec_t *ops_arr, 772 size_t *ops_arr_len); 773 774 775 /* 776 * Looks up an opspec based on an iga::Op value. 777 * 'gen' gen plaform 778 * 'op' the operation value to lookup; this is an iga::Op; 779 * an invalid op will succeed but return Op::INVALID 780 * 'os' the output value 781 * 782 * RETURNS: 783 * IGA_SUCCESS upon success 784 * IGA_INVALID_ARG if an argument is invalid 785 * (invalid GEN or op or null os) 786 */ 787 IGA_API iga_status_t iga_opspec_from_op( 788 iga_gen_t gen, 789 /* iga::Op */ uint32_t op_enum, 790 iga_opspec_t *os); 791 792 793 /* 794 * Lists the mnemonic name for a given op (e.g. "sends") 795 * (has similar semantics regarding the parameters as 'iga_opspec_enum') 796 * 797 * RETURNS: 798 * IGA_SUCCESS upon success 799 * IGA_INVALID_ARG if given an invalid argument 800 */ 801 IGA_API iga_status_t iga_opspec_mnemonic( 802 const iga_opspec_t op, 803 char *mnemonic, 804 size_t *mnemonic_len); 805 806 807 /* 808 * Lists the op name for a given op (e.g. "Split Send Message") 809 * (has similar semantics regarding the parameters as 'iga_opspec_enum') 810 * 811 * RETURNS: 812 * IGA_SUCCESS upon success 813 * IGA_INVALID_ARG if a gen argument invalid 814 */ 815 IGA_API iga_status_t iga_opspec_name( 816 const iga_opspec_t op, 817 char *name, 818 size_t *name_len); 819 820 821 /* 822 * Lists the op desription for a given op 823 * (has similar semantics regarding the parameters as 'iga_opspec_enum') 824 * 825 * RETURNS: 826 * IGA_SUCCESS upon success 827 * IGA_INVALID_ARG if a gen argument invalid 828 */ 829 IGA_API iga_status_t iga_opspec_description( 830 iga_opspec_t op, 831 char *desc, 832 size_t *desc_len); 833 834 835 /* 836 * Returns iga::Op for this operation as a uint32_t 837 * 838 * RETURNS: 839 * IGA_SUCCESS upon success 840 * IGA_INVALID_ARG if an argument is NULL 841 */ 842 IGA_API iga_status_t iga_opspec_op( 843 iga_opspec_t os, 844 uint32_t *op); 845 846 847 /* 848 * Returns iga::Op value opcode encoding. This can vary for the same op 849 * on platform to platform. 850 * 851 * RETURNS: 852 * IGA_SUCCESS upon success 853 * IGA_INVALID_ARG if an argument is NULL 854 */ 855 IGA_API iga_status_t iga_opspec_op_encoding( 856 iga_opspec_t op, 857 uint32_t *opcode); 858 859 #ifdef __cplusplus 860 } 861 #endif 862 863 #endif 864