1 /** 2 * \file libyasm/arch.h 3 * \brief YASM architecture interface. 4 * 5 * \license 6 * Copyright (C) 2002-2007 Peter Johnson 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * \endlicense 29 */ 30 #ifndef YASM_ARCH_H 31 #define YASM_ARCH_H 32 33 /** Errors that may be returned by yasm_arch_module::create(). */ 34 typedef enum yasm_arch_create_error { 35 YASM_ARCH_CREATE_OK = 0, /**< No error. */ 36 YASM_ARCH_CREATE_BAD_MACHINE, /**< Unrecognized machine name. */ 37 YASM_ARCH_CREATE_BAD_PARSER /**< Unrecognized parser name. */ 38 } yasm_arch_create_error; 39 40 /** Return values for yasm_arch_module::parse_check_insnprefix(). */ 41 typedef enum yasm_arch_insnprefix { 42 YASM_ARCH_NOTINSNPREFIX = 0, /**< Unrecognized */ 43 YASM_ARCH_INSN, /**< An instruction */ 44 YASM_ARCH_PREFIX /**< An instruction prefix */ 45 } yasm_arch_insnprefix; 46 47 /** Types of registers / target modifiers that may be returned by 48 * yasm_arch_module::parse_check_regtmod(). 49 */ 50 typedef enum yasm_arch_regtmod { 51 YASM_ARCH_NOTREGTMOD = 0, /**< Unrecognized */ 52 YASM_ARCH_REG, /**< A "normal" register */ 53 YASM_ARCH_REGGROUP, /**< A group of indexable registers */ 54 YASM_ARCH_SEGREG, /**< A segment register */ 55 YASM_ARCH_TARGETMOD /**< A target modifier (for jumps) */ 56 } yasm_arch_regtmod; 57 58 #ifndef YASM_DOXYGEN 59 /** Base #yasm_arch structure. Must be present as the first element in any 60 * #yasm_arch implementation. 61 */ 62 typedef struct yasm_arch_base { 63 /** #yasm_arch_module implementation for this architecture. */ 64 const struct yasm_arch_module *module; 65 } yasm_arch_base; 66 #endif 67 68 /** YASM machine subtype. A number of different machine types may be 69 * associated with a single architecture. These may be specific CPU's, but 70 * the ABI used to interface with the architecture should be the primary 71 * differentiator between machines. Some object formats (ELF) use the machine 72 * to determine parameters within the generated output. 73 */ 74 typedef struct yasm_arch_machine { 75 /** One-line description of the machine. */ 76 const char *name; 77 78 /** Keyword used to select machine. */ 79 const char *keyword; 80 } yasm_arch_machine; 81 82 /** YASM architecture module interface. 83 * \note All "data" in parser-related functions (yasm_arch_parse_*) needs to 84 * start the parse initialized to 0 to make it okay for a parser-related 85 * function to use/check previously stored data to see if it's been 86 * called before on the same piece of data. 87 */ 88 typedef struct yasm_arch_module { 89 /** One-line description of the architecture. 90 * Call yasm_arch_name() to get the name of a particular #yasm_arch. 91 */ 92 const char *name; 93 94 /** Keyword used to select architecture. 95 * Call yasm_arch_keyword() to get the keyword of a particular #yasm_arch. 96 */ 97 const char *keyword; 98 99 /** NULL-terminated list of directives. NULL if none. */ 100 /*@null@*/ const yasm_directive *directives; 101 102 /** Create architecture. 103 * Module-level implementation of yasm_arch_create(). 104 * Call yasm_arch_create() instead of calling this function. 105 */ 106 /*@only@*/ yasm_arch * (*create) (const char *machine, const char *parser, 107 /*@out@*/ yasm_arch_create_error *error); 108 109 /** Module-level implementation of yasm_arch_destroy(). 110 * Call yasm_arch_destroy() instead of calling this function. 111 */ 112 void (*destroy) (/*@only@*/ yasm_arch *arch); 113 114 /** Module-level implementation of yasm_arch_get_machine(). 115 * Call yasm_arch_get_machine() instead of calling this function. 116 */ 117 const char * (*get_machine) (const yasm_arch *arch); 118 119 /** Module-level implementation of yasm_arch_get_address_size(). 120 * Call yasm_arch_get_address_size() instead of calling this function. 121 */ 122 unsigned int (*get_address_size) (const yasm_arch *arch); 123 124 /** Module-level implementation of yasm_arch_set_var(). 125 * Call yasm_arch_set_var() instead of calling this function. 126 */ 127 int (*set_var) (yasm_arch *arch, const char *var, unsigned long val); 128 129 /** Module-level implementation of yasm_arch_parse_check_insnprefix(). 130 * Call yasm_arch_parse_check_insnprefix() instead of calling this function. 131 */ 132 yasm_arch_insnprefix (*parse_check_insnprefix) 133 (yasm_arch *arch, const char *id, size_t id_len, unsigned long line, 134 /*@out@*/ /*@only@*/ yasm_bytecode **bc, /*@out@*/ uintptr_t *prefix); 135 136 /** Module-level implementation of yasm_arch_parse_check_regtmod(). 137 * Call yasm_arch_parse_check_regtmod() instead of calling this function. 138 */ 139 yasm_arch_regtmod (*parse_check_regtmod) 140 (yasm_arch *arch, const char *id, size_t id_len, 141 /*@out@*/ uintptr_t *data); 142 143 /** Module-level implementation of yasm_arch_get_fill(). 144 * Call yasm_arch_get_fill() instead of calling this function. 145 */ 146 const unsigned char ** (*get_fill) (const yasm_arch *arch); 147 148 /** Module-level implementation of yasm_arch_floatnum_tobytes(). 149 * Call yasm_arch_floatnum_tobytes() instead of calling this function. 150 */ 151 int (*floatnum_tobytes) (yasm_arch *arch, const yasm_floatnum *flt, 152 unsigned char *buf, size_t destsize, 153 size_t valsize, size_t shift, int warn); 154 155 /** Module-level implementation of yasm_arch_intnum_tobytes(). 156 * Call yasm_arch_intnum_tobytes() instead of calling this function. 157 */ 158 int (*intnum_tobytes) (yasm_arch *arch, const yasm_intnum *intn, 159 unsigned char *buf, size_t destsize, size_t valsize, 160 int shift, const yasm_bytecode *bc, 161 int warn); 162 163 /** Module-level implementation of yasm_arch_get_reg_size(). 164 * Call yasm_arch_get_reg_size() instead of calling this function. 165 */ 166 unsigned int (*get_reg_size) (yasm_arch *arch, uintptr_t reg); 167 168 /** Module-level implementation of yasm_arch_reggroup_get_reg(). 169 * Call yasm_arch_reggroup_get_reg() instead of calling this function. 170 */ 171 uintptr_t (*reggroup_get_reg) (yasm_arch *arch, uintptr_t reggroup, 172 unsigned long regindex); 173 174 /** Module-level implementation of yasm_arch_reg_print(). 175 * Call yasm_arch_reg_print() instead of calling this function. 176 */ 177 void (*reg_print) (yasm_arch *arch, uintptr_t reg, FILE *f); 178 179 /** Module-level implementation of yasm_arch_segreg_print(). 180 * Call yasm_arch_segreg_print() instead of calling this function. 181 */ 182 void (*segreg_print) (yasm_arch *arch, uintptr_t segreg, FILE *f); 183 184 /** Module-level implementation of yasm_arch_ea_create(). 185 * Call yasm_arch_ea_create() instead of calling this function. 186 */ 187 yasm_effaddr * (*ea_create) (yasm_arch *arch, /*@keep@*/ yasm_expr *e); 188 189 /** Module-level implementation of yasm_arch_ea_destroy(). 190 * Call yasm_arch_ea_destroy() instead of calling this function. 191 */ 192 void (*ea_destroy) (/*@only@*/ yasm_effaddr *ea); 193 194 /** Module-level implementation of yasm_arch_ea_print(). 195 * Call yasm_arch_ea_print() instead of calling this function. 196 */ 197 void (*ea_print) (const yasm_effaddr *ea, FILE *f, int indent_level); 198 199 /** Module-level implementation of yasm_arch_create_empty_insn(). 200 * Call yasm_arch_create_empty_insn() instead of calling this function. 201 */ 202 /*@only@*/ yasm_bytecode * (*create_empty_insn) (yasm_arch *arch, 203 unsigned long line); 204 205 /** NULL-terminated list of machines for this architecture. 206 * Call yasm_arch_get_machine() to get the active machine of a particular 207 * #yasm_arch. 208 */ 209 const yasm_arch_machine *machines; 210 211 /** Default machine keyword. 212 * Call yasm_arch_get_machine() to get the active machine of a particular 213 * #yasm_arch. 214 */ 215 const char *default_machine_keyword; 216 217 /** Canonical "word" size in bits. 218 * Call yasm_arch_wordsize() to get the word size of a particular 219 * #yasm_arch. 220 */ 221 unsigned int wordsize; 222 223 /** Worst case minimum instruction length in bytes. 224 * Call yasm_arch_min_insn_len() to get the minimum instruction length of 225 * a particular #yasm_arch. 226 */ 227 unsigned int min_insn_len; 228 } yasm_arch_module; 229 230 /** Get the one-line description of an architecture. 231 * \param arch architecture 232 * \return One-line description of architecture. 233 */ 234 const char *yasm_arch_name(const yasm_arch *arch); 235 236 /** Get the keyword used to select an architecture. 237 * \param arch architecture 238 * \return Architecture keyword. 239 */ 240 const char *yasm_arch_keyword(const yasm_arch *arch); 241 242 /** Get the word size of an architecture. 243 * \param arch architecture 244 * \return Word size (in bits). 245 */ 246 unsigned int yasm_arch_wordsize(const yasm_arch *arch); 247 248 /** Get the minimum instruction length of an architecture. 249 * \param arch architecture 250 * \return Minimum instruction length (in bytes). 251 */ 252 unsigned int yasm_arch_min_insn_len(const yasm_arch *arch); 253 254 /** Create architecture. 255 * \param module architecture module 256 * \param machine keyword of machine in use (must be one listed in 257 * #yasm_arch_module.machines) 258 * \param parser keyword of parser in use 259 * \param error error return value 260 * \return NULL on error (error returned in error parameter), otherwise new 261 * architecture. 262 */ 263 /*@only@*/ yasm_arch *yasm_arch_create(const yasm_arch_module *module, 264 const char *machine, const char *parser, 265 /*@out@*/ yasm_arch_create_error *error); 266 267 /** Clean up, free any architecture-allocated memory. 268 * \param arch architecture 269 */ 270 void yasm_arch_destroy(/*@only@*/ yasm_arch *arch); 271 272 /** Get architecture's active machine name. 273 * \param arch architecture 274 * \return Active machine name. 275 */ 276 const char *yasm_arch_get_machine(const yasm_arch *arch); 277 278 /** Get architecture's active address size, in bits. 279 * \param arch architecture 280 * \return Active address size (in bits). 281 */ 282 unsigned int yasm_arch_get_address_size(const yasm_arch *arch); 283 284 /** Set any arch-specific variables. For example, "mode_bits" in x86. 285 * \param arch architecture 286 * \param var variable name 287 * \param val value to set 288 * \return Zero on success, non-zero on failure (variable does not exist). 289 */ 290 int yasm_arch_set_var(yasm_arch *arch, const char *var, unsigned long val); 291 292 /** Check an generic identifier to see if it matches architecture specific 293 * names for instructions or instruction prefixes. Unrecognized identifiers 294 * should return #YASM_ARCH_NOTINSNPREFIX so they can be treated as normal 295 * symbols. Any additional data beyond just the type (almost always necessary) 296 * should be returned into the space provided by the data parameter. 297 * \param arch architecture 298 * \param id identifier as in the input file 299 * \param id_len length of id string 300 * \param line virtual line 301 * \param bc for instructions, yasm_insn-based bytecode is returned 302 * (and NULL otherwise) 303 * \param prefix for prefixes, yasm_arch-specific value is returned 304 * (and 0 otherwise) 305 * \return Identifier type (#YASM_ARCH_NOTINSNPREFIX if unrecognized) 306 */ 307 yasm_arch_insnprefix yasm_arch_parse_check_insnprefix 308 (yasm_arch *arch, const char *id, size_t id_len, unsigned long line, 309 /*@out@*/ /*@only@*/ yasm_bytecode **bc, /*@out@*/ uintptr_t *prefix); 310 311 /** Check an generic identifier to see if it matches architecture specific 312 * names for registers or target modifiers. Unrecognized identifiers should 313 * return #YASM_ARCH_NOTREGTMOD. Any additional data beyond just the type 314 * (almost always necessary) should be returned into the space provided by the 315 * data parameter. 316 * \param arch architecture 317 * \param id identifier as in the input file 318 * \param id_len length of id string 319 * \param data extra identification information (yasm_arch-specific) 320 * [output] 321 * \return Identifier type (#YASM_ARCH_NOTREGTMOD if unrecognized) 322 */ 323 yasm_arch_regtmod yasm_arch_parse_check_regtmod 324 (yasm_arch *arch, const char *id, size_t id_len, 325 /*@out@*/ uintptr_t *data); 326 327 /** Get NOP fill patterns for 1-15 bytes of fill. 328 * \param arch architecture 329 * \return 16-entry array of arrays; [0] is unused, [1] - [15] point to arrays 330 * of 1-15 bytes (respectively) in length. 331 */ 332 const unsigned char **yasm_arch_get_fill(const yasm_arch *arch); 333 334 /** Output #yasm_floatnum to buffer. Puts the value into the least 335 * significant bits of the destination, or may be shifted into more 336 * significant bits by the shift parameter. The destination bits are 337 * cleared before being set. 338 * Architecture-specific because of endianness. 339 * \param arch architecture 340 * \param flt floating point value 341 * \param buf buffer to write into 342 * \param destsize destination size (in bytes) 343 * \param valsize size (in bits) 344 * \param shift left shift (in bits) 345 * \param warn enables standard overflow/underflow warnings 346 * \return Nonzero on error. 347 */ 348 int yasm_arch_floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt, 349 unsigned char *buf, size_t destsize, 350 size_t valsize, size_t shift, int warn); 351 352 /** Output #yasm_intnum to buffer. Puts the value into the least 353 * significant bits of the destination, or may be shifted into more 354 * significant bits by the shift parameter. The destination bits are 355 * cleared before being set. 356 * \param arch architecture 357 * \param intn integer value 358 * \param buf buffer to write into 359 * \param destsize destination size (in bytes) 360 * \param valsize size (in bits) 361 * \param shift left shift (in bits); may be negative to specify right 362 * shift (standard warnings include truncation to boundary) 363 * \param bc bytecode being output ("parent" of value) 364 * \param warn enables standard warnings (value doesn't fit into 365 * valsize bits) 366 * \return Nonzero on error. 367 */ 368 int yasm_arch_intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn, 369 unsigned char *buf, size_t destsize, 370 size_t valsize, int shift, 371 const yasm_bytecode *bc, int warn); 372 373 /** Get the equivalent size of a register in bits. 374 * \param arch architecture 375 * \param reg register 376 * \return 0 if there is no suitable equivalent size, otherwise the size. 377 */ 378 unsigned int yasm_arch_get_reg_size(yasm_arch *arch, uintptr_t reg); 379 380 /** Get a specific register of a register group, based on the register 381 * group and the index within the group. 382 * \param arch architecture 383 * \param reggroup register group 384 * \param regindex register index 385 * \return 0 if regindex is not valid for that register group, otherwise the 386 * specific register value. 387 */ 388 uintptr_t yasm_arch_reggroup_get_reg(yasm_arch *arch, uintptr_t reggroup, 389 unsigned long regindex); 390 391 /** Print a register. For debugging purposes. 392 * \param arch architecture 393 * \param reg register 394 * \param f file 395 */ 396 void yasm_arch_reg_print(yasm_arch *arch, uintptr_t reg, FILE *f); 397 398 /** Print a segment register. For debugging purposes. 399 * \param arch architecture 400 * \param segreg segment register 401 * \param f file 402 */ 403 void yasm_arch_segreg_print(yasm_arch *arch, uintptr_t segreg, FILE *f); 404 405 /** Create an effective address from an expression. 406 * \param arch architecture 407 * \param e expression (kept, do not delete) 408 * \return Newly allocated effective address. 409 */ 410 yasm_effaddr *yasm_arch_ea_create(yasm_arch *arch, /*@keep@*/ yasm_expr *e); 411 412 /** Delete (free allocated memory for) an effective address. 413 * \param arch architecture 414 * \param ea effective address (only pointer to it). 415 */ 416 void yasm_arch_ea_destroy(yasm_arch *arch, /*@only@*/ yasm_effaddr *ea); 417 418 /** Print an effective address. For debugging purposes. 419 * \param arch architecture 420 * \param ea effective address 421 * \param f file 422 * \param indent_level indentation level 423 */ 424 void yasm_arch_ea_print(const yasm_arch *arch, const yasm_effaddr *ea, 425 FILE *f, int indent_level); 426 427 /** Create a bytecode that represents a single empty (0 length) instruction. 428 * This is used for handling solitary prefixes. 429 * \param arch architecture 430 * \param line virtual line (from yasm_linemap) 431 * \return Newly allocated bytecode. 432 */ 433 /*@only@*/ yasm_bytecode *yasm_arch_create_empty_insn(yasm_arch *arch, 434 unsigned long line); 435 436 #ifndef YASM_DOXYGEN 437 438 /* Inline macro implementations for arch functions */ 439 440 #define yasm_arch_name(arch) \ 441 (((yasm_arch_base *)arch)->module->name) 442 #define yasm_arch_keyword(arch) \ 443 (((yasm_arch_base *)arch)->module->keyword) 444 #define yasm_arch_wordsize(arch) \ 445 (((yasm_arch_base *)arch)->module->wordsize) 446 #define yasm_arch_min_insn_len(arch) \ 447 (((yasm_arch_base *)arch)->module->min_insn_len) 448 449 #define yasm_arch_create(module, machine, parser, error) \ 450 module->create(machine, parser, error) 451 452 #define yasm_arch_destroy(arch) \ 453 ((yasm_arch_base *)arch)->module->destroy(arch) 454 #define yasm_arch_get_machine(arch) \ 455 ((yasm_arch_base *)arch)->module->get_machine(arch) 456 #define yasm_arch_get_address_size(arch) \ 457 ((yasm_arch_base *)arch)->module->get_address_size(arch) 458 #define yasm_arch_set_var(arch, var, val) \ 459 ((yasm_arch_base *)arch)->module->set_var(arch, var, val) 460 #define yasm_arch_parse_check_insnprefix(arch, id, id_len, line, bc, prefix) \ 461 ((yasm_arch_base *)arch)->module->parse_check_insnprefix \ 462 (arch, id, id_len, line, bc, prefix) 463 #define yasm_arch_parse_check_regtmod(arch, id, id_len, data) \ 464 ((yasm_arch_base *)arch)->module->parse_check_regtmod \ 465 (arch, id, id_len, data) 466 #define yasm_arch_get_fill(arch) \ 467 ((yasm_arch_base *)arch)->module->get_fill(arch) 468 #define yasm_arch_floatnum_tobytes(arch, flt, buf, destsize, valsize, shift, \ 469 warn) \ 470 ((yasm_arch_base *)arch)->module->floatnum_tobytes \ 471 (arch, flt, buf, destsize, valsize, shift, warn) 472 #define yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize, shift, \ 473 bc, warn) \ 474 ((yasm_arch_base *)arch)->module->intnum_tobytes \ 475 (arch, intn, buf, destsize, valsize, shift, bc, warn) 476 #define yasm_arch_get_reg_size(arch, reg) \ 477 ((yasm_arch_base *)arch)->module->get_reg_size(arch, reg) 478 #define yasm_arch_reggroup_get_reg(arch, regg, regi) \ 479 ((yasm_arch_base *)arch)->module->reggroup_get_reg(arch, regg, regi) 480 #define yasm_arch_reg_print(arch, reg, f) \ 481 ((yasm_arch_base *)arch)->module->reg_print(arch, reg, f) 482 #define yasm_arch_segreg_print(arch, segreg, f) \ 483 ((yasm_arch_base *)arch)->module->segreg_print(arch, segreg, f) 484 #define yasm_arch_ea_create(arch, e) \ 485 ((yasm_arch_base *)arch)->module->ea_create(arch, e) 486 #define yasm_arch_ea_destroy(arch, ea) \ 487 ((yasm_arch_base *)arch)->module->ea_destroy(ea) 488 #define yasm_arch_ea_print(arch, ea, f, i) \ 489 ((yasm_arch_base *)arch)->module->ea_print(ea, f, i) 490 #define yasm_arch_create_empty_insn(arch, line) \ 491 ((yasm_arch_base *)arch)->module->create_empty_insn(arch, line) 492 493 #endif 494 495 #endif 496