Home | History | Annotate | Download | only in libyasm
      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