1 /**
2  * \file libyasm/objfmt.h
3  * \brief YASM object format module interface.
4  *
5  * \license
6  *  Copyright (C) 2001-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_OBJFMT_H
31 #define YASM_OBJFMT_H
32 
33 #ifndef YASM_DOXYGEN
34 /** Base #yasm_objfmt structure.  Must be present as the first element in any
35  * #yasm_objfmt implementation.
36  */
37 typedef struct yasm_objfmt_base {
38     /** #yasm_objfmt_module implementation for this object format. */
39     const struct yasm_objfmt_module *module;
40 } yasm_objfmt_base;
41 #endif
42 
43 /** Object format module interface. */
44 struct yasm_objfmt_module {
45     /** One-line description of the object format. */
46     const char *name;
47 
48     /** Keyword used to select object format. */
49     const char *keyword;
50 
51     /** Default output file extension (without the '.').
52      * NULL means no extension, with no '.', while "" includes the '.'.
53      */
54     /*@null@*/ const char *extension;
55 
56     /** Default (starting) x86 BITS setting.  This only appies to the x86
57      * architecture; other architectures ignore this setting.
58      */
59     const unsigned char default_x86_mode_bits;
60 
61     /** If @ signs should be legal in identifiers. */
62     const unsigned char id_at_ok;
63 
64     /** NULL-terminated list of debug format (yasm_dbgfmt) keywords that are
65      * valid to use with this object format.  The null debug format
66      * (null_dbgfmt, "null") should always be in this list so it's possible to
67      * have no debug output.
68      */
69     const char **dbgfmt_keywords;
70 
71     /** Default debug format keyword (set even if there's only one available to
72      * use).
73      */
74     const char *default_dbgfmt_keyword;
75 
76     /** NULL-terminated list of directives.  NULL if none. */
77     /*@null@*/ const yasm_directive *directives;
78 
79     /** NULL-terminated list of standard macro lookups.  NULL if none. */
80     const yasm_stdmac *stdmacs;
81 
82     /** Create object format.
83      * Module-level implementation of yasm_objfmt_create().
84      * Call yasm_objfmt_create() instead of calling this function.
85      * \param object            object
86      * \param a                 architecture in use
87      * \return NULL if architecture/machine combination not supported.
88      */
89     /*@null@*/ /*@only@*/ yasm_objfmt * (*create) (yasm_object *object);
90 
91     /** Module-level implementation of yasm_objfmt_output().
92      * Call yasm_objfmt_output() instead of calling this function.
93      */
94     void (*output) (yasm_object *o, FILE *f, int all_syms,
95                     yasm_errwarns *errwarns);
96 
97     /** Module-level implementation of yasm_objfmt_destroy().
98      * Call yasm_objfmt_destroy() instead of calling this function.
99      */
100     void (*destroy) (/*@only@*/ yasm_objfmt *objfmt);
101 
102     /** Module-level implementation of yasm_objfmt_add_default_section().
103      * Call yasm_objfmt_add_default_section() instead of calling this function.
104      */
105     yasm_section * (*add_default_section) (yasm_object *object);
106 
107     /** Module-level implementation of yasm_objfmt_init_new_section().
108      * Call yasm_objfmt_init_new_section() instead of calling this function.
109      */
110     void (*init_new_section) (yasm_section *section, unsigned long line);
111 
112     /** Module-level implementation of yasm_objfmt_section_switch().
113      * Call yasm_objfmt_section_switch() instead of calling this function.
114      */
115     /*@observer@*/ /*@null@*/ yasm_section *
116         (*section_switch)(yasm_object *object, yasm_valparamhead *valparams,
117                           /*@null@*/ yasm_valparamhead *objext_valparams,
118                           unsigned long line);
119 
120     /** Module-level implementation of yasm_objfmt_get_special_sym().
121      * Call yasm_objfmt_get_special_sym() instead of calling this function.
122      */
123     /*@observer@*/ /*@null@*/ yasm_symrec *
124         (*get_special_sym)(yasm_object *object, const char *name,
125                            const char *parser);
126 };
127 
128 /** Create object format.
129  * \param module        object format module
130  * \param object        object
131  * \return NULL if architecture/machine combination not supported.
132  */
133 /*@null@*/ /*@only@*/ yasm_objfmt *yasm_objfmt_create
134     (const yasm_objfmt_module *module, yasm_object *object);
135 
136 /** Write out (post-optimized) sections to the object file.
137  * This function may call yasm_symrec_* functions as necessary (including
138  * yasm_symrec_traverse()) to retrieve symbolic information.
139  * \param object        object
140  * \param f             output object file
141  * \param all_syms      if nonzero, all symbols should be included in
142  *                      the object file
143  * \param errwarns      error/warning set
144  * \note Errors and warnings are stored into errwarns.
145  */
146 void yasm_objfmt_output(yasm_object *object, FILE *f, int all_syms,
147                         yasm_errwarns *errwarns);
148 
149 /** Cleans up any allocated object format memory.
150  * \param objfmt        object format
151  */
152 void yasm_objfmt_destroy(/*@only@*/ yasm_objfmt *objfmt);
153 
154 /** Add a default section to an object.
155  * \param object    object
156  * \return Default section.
157  */
158 yasm_section *yasm_objfmt_add_default_section(yasm_object *object);
159 
160 /** Initialize the object-format specific portion of a section.  Called
161  * by yasm_object_get_general(); in general should not be directly called.
162  * \param section   section
163  * \param line      virtual line (from yasm_linemap)
164  */
165 void yasm_objfmt_init_new_section(yasm_object *object, unsigned long line);
166 
167 /** Switch object file sections.  The first val of the valparams should
168  * be the section name.  Calls yasm_object_get_general() to actually get
169  * the section.
170  * \param object                object
171  * \param valparams             value/parameters
172  * \param objext_valparams      object format-specific value/parameters
173  * \param line                  virtual line (from yasm_linemap)
174  * \return NULL on error, otherwise new section.
175  */
176 /*@observer@*/ /*@null@*/ yasm_section *yasm_objfmt_section_switch
177     (yasm_object *object, yasm_valparamhead *valparams,
178      /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line);
179 
180 /** Get a special symbol.  Special symbols are generally used to generate
181  * special relocation types via the WRT mechanism.
182  * \param object        object
183  * \param name          symbol name (not including any parser-specific prefix)
184  * \param parser        parser keyword
185  * \return NULL if unrecognized, otherwise special symbol.
186  */
187 /*@observer@*/ /*@null@*/ yasm_symrec *yasm_objfmt_get_special_sym
188     (yasm_object *object, const char *name, const char *parser);
189 
190 #ifndef YASM_DOXYGEN
191 
192 /* Inline macro implementations for objfmt functions */
193 
194 #define yasm_objfmt_create(module, object) module->create(object)
195 
196 #define yasm_objfmt_output(object, f, all_syms, ews) \
197     ((yasm_objfmt_base *)((object)->objfmt))->module->output \
198         (object, f, all_syms, ews)
199 #define yasm_objfmt_destroy(objfmt) \
200     ((yasm_objfmt_base *)objfmt)->module->destroy(objfmt)
201 #define yasm_objfmt_section_switch(object, vpms, oe_vpms, line) \
202     ((yasm_objfmt_base *)((object)->objfmt))->module->section_switch \
203         (object, vpms, oe_vpms, line)
204 #define yasm_objfmt_add_default_section(object) \
205     ((yasm_objfmt_base *)((object)->objfmt))->module->add_default_section \
206         (object)
207 #define yasm_objfmt_init_new_section(section, line) \
208     ((yasm_objfmt_base *)((object)->objfmt))->module->init_new_section \
209         (section, line)
210 #define yasm_objfmt_get_special_sym(object, name, parser) \
211     ((yasm_objfmt_base *)((object)->objfmt))->module->get_special_sym \
212         (object, name, parser)
213 
214 #endif
215 
216 #endif
217