Home | History | Annotate | Download | only in libyasm
      1 /*
      2  * YASM module loader
      3  *
      4  *  Copyright (C) 2004-2007  Peter Johnson
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
     16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
     19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  * POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 #include <util.h>
     28 
     29 #include <libyasm.h>
     30 
     31 
     32 typedef struct module {
     33     const char *keyword;            /* module keyword */
     34     void *data;                     /* associated data */
     35 } module;
     36 
     37 EXTERN_LIST
     38 
     39 static module arch_modules[] = {
     40 MODULES_arch_
     41 };
     42 
     43 static module dbgfmt_modules[] = {
     44 MODULES_dbgfmt_
     45 };
     46 
     47 static module objfmt_modules[] = {
     48 MODULES_objfmt_
     49 };
     50 
     51 static module listfmt_modules[] = {
     52 MODULES_listfmt_
     53 };
     54 
     55 static module parser_modules[] = {
     56 MODULES_parser_
     57 };
     58 
     59 static module preproc_modules[] = {
     60 MODULES_preproc_
     61 };
     62 
     63 static struct {
     64     module *m;
     65     size_t n;
     66 } module_types[] = {
     67     {arch_modules, sizeof(arch_modules)/sizeof(module)},
     68     {dbgfmt_modules, sizeof(dbgfmt_modules)/sizeof(module)},
     69     {objfmt_modules, sizeof(objfmt_modules)/sizeof(module)},
     70     {listfmt_modules, sizeof(listfmt_modules)/sizeof(module)},
     71     {parser_modules, sizeof(parser_modules)/sizeof(module)},
     72     {preproc_modules, sizeof(preproc_modules)/sizeof(module)},
     73 };
     74 
     75 typedef struct loaded_module {
     76     yasm_module_type type;          /* module type */
     77     const char *keyword;            /* module keyword */
     78     void *data;                     /* associated data */
     79 } loaded_module;
     80 
     81 static loaded_module *loaded_modules = NULL;
     82 static size_t num_loaded_modules = 0;
     83 
     84 void *
     85 yasm_load_module(yasm_module_type type, const char *keyword)
     86 {
     87     size_t i;
     88     module *modules;
     89     size_t n;
     90 
     91     /* Look for the module/symbol, first in loaded modules */
     92     if (loaded_modules) {
     93         for (i=0; i<num_loaded_modules; i++) {
     94             if (loaded_modules[i].type == type &&
     95                 yasm__strcasecmp(loaded_modules[i].keyword, keyword) == 0)
     96                 return loaded_modules[i].data;
     97         }
     98     }
     99 
    100     modules = module_types[type].m;
    101     n = module_types[type].n;
    102     for (i=0; i<n; i++) {
    103         if (yasm__strcasecmp(modules[i].keyword, keyword) == 0)
    104             return modules[i].data;
    105     }
    106 
    107     return NULL;
    108 }
    109 
    110 void
    111 yasm_register_module(yasm_module_type type, const char *keyword, void *data)
    112 {
    113     loaded_modules =
    114         yasm_xrealloc(loaded_modules,
    115                       (num_loaded_modules+1)*sizeof(loaded_module));
    116     loaded_modules[num_loaded_modules].type = type;
    117     loaded_modules[num_loaded_modules].keyword = keyword;
    118     loaded_modules[num_loaded_modules].data = data;
    119     num_loaded_modules++;
    120 }
    121 
    122 static void
    123 yasm_list_one_module(yasm_module_type type, void *data,
    124                      void (*printfunc) (const char *name, const char *keyword))
    125 {
    126     yasm_arch_module *arch;
    127     yasm_dbgfmt_module *dbgfmt;
    128     yasm_objfmt_module *objfmt;
    129     yasm_listfmt_module *listfmt;
    130     yasm_parser_module *parser;
    131     yasm_preproc_module *preproc;
    132 
    133     switch (type) {
    134         case YASM_MODULE_ARCH:
    135             arch = data;
    136             printfunc(arch->name, arch->keyword);
    137             break;
    138         case YASM_MODULE_DBGFMT:
    139             dbgfmt = data;
    140             printfunc(dbgfmt->name, dbgfmt->keyword);
    141             break;
    142         case YASM_MODULE_OBJFMT:
    143             objfmt = data;
    144             printfunc(objfmt->name, objfmt->keyword);
    145             break;
    146         case YASM_MODULE_LISTFMT:
    147             listfmt = data;
    148             printfunc(listfmt->name, listfmt->keyword);
    149             break;
    150         case YASM_MODULE_PARSER:
    151             parser = data;
    152             printfunc(parser->name, parser->keyword);
    153             break;
    154         case YASM_MODULE_PREPROC:
    155             preproc = data;
    156             printfunc(preproc->name, preproc->keyword);
    157             break;
    158     }
    159 }
    160 
    161 void
    162 yasm_list_modules(yasm_module_type type,
    163                   void (*printfunc) (const char *name, const char *keyword))
    164 {
    165     size_t i;
    166     module *modules;
    167     size_t n;;
    168 
    169     /* Go through available list, and try to load each one */
    170     if (loaded_modules) {
    171         for (i=0; i<num_loaded_modules; i++)
    172             yasm_list_one_module(type, loaded_modules[i].data, printfunc);
    173     }
    174 
    175     modules = module_types[type].m;
    176     n = module_types[type].n;
    177     for (i=0; i<n; i++)
    178         yasm_list_one_module(type, modules[i].data, printfunc);
    179 }
    180