1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2020 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
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
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
44 uint64_t realsize(enum out_type type
, uint64_t size
);
46 /* Do-nothing versions of some output routines */
48 null_directive(enum directive directive
, char *value
);
49 void null_sectalign(int32_t seg
, unsigned int value
);
50 void null_reset(void);
51 int32_t null_segbase(int32_t seg
);
53 /* Do-nothing versions of all the debug routines */
54 void null_debug_init(void);
55 void null_debug_linenum(const char *filename
, int32_t linenumber
,
57 void null_debug_deflabel(char *name
, int32_t segment
, int64_t offset
,
58 int is_global
, char *special
);
59 void null_debug_directive(const char *directive
, const char *params
);
60 void null_debug_typevalue(int32_t type
);
61 void null_debug_output(int type
, void *param
);
62 void null_debug_cleanup(void);
63 extern const struct dfmt
* const null_debug_arr
[2];
65 /* Wrapper for unported backends */
66 void nasm_do_legacy_output(const struct out_data
*data
);
69 * Common routines for tasks that really should migrate into the core.
70 * This provides a common interface for maintaining sections and symbols,
71 * and provide quick lookups as well as declared-order sequential walks.
73 * These structures are intended to be embedded at the *top* of a
74 * backend-specific structure containing additional information.
76 * The tokens O_Section, O_Symbol and O_Reloc are intended to be
77 * defined as macros by the backend before including this file!
84 typedef struct ol_sect O_Section
;
87 typedef struct ol_sym O_Symbol
;
90 typedef void * O_Reloc
;
93 /* Common section structure */
96 * Common flags for sections and symbols; low values reserved for
97 * backend. Note that both ol_sect and ol_sym begin with a flags
98 * field, so if a section pointer points to an external symbol instead
99 * they can be trivially resolved.
101 #define OF_SYMBOL 0x80000000
102 #define OF_GLOBAL 0x40000000
103 #define OF_IMPSEC 0x20000000
104 #define OF_COMMON 0x10000000
109 struct ol_symlist
*next
;
113 struct ol_symlist
*head
, **tail
;
119 uint32_t flags
; /* Section/symbol flags */
120 struct ol_sect
*next
; /* Next section in declared order */
121 const char *name
; /* Name of section */
122 struct ol_symhead syml
; /* All symbols in this section */
123 struct ol_symhead symg
; /* Global symbols in this section */
124 struct SAA
*data
; /* Contents of section */
125 struct SAA
*reloc
; /* Section relocations */
126 uint32_t index
; /* Primary section index */
127 uint32_t subindex
; /* Current subsection index */
130 /* Segment reference */
132 OS_NOSEG
= 0, /* Plain number (no segment) */
133 OS_SEGREF
= 1, /* It is a segment reference */
134 OS_ABS
= 1, /* Absolute segment reference */
135 OS_SECT
= 2, /* It is a real section */
136 OS_OFFS
= OS_SECT
, /* Offset reference in section */
137 OS_SEG
= OS_SECT
|OS_SEGREF
/* Section reference */
141 struct ol_sect
*sect
; /* Section structure */
142 struct ol_sym
*sym
; /* External symbol structure */
150 * For a section: subsection index
151 * For a metasymbol: virtual segment index
152 * For an absolute symbol: absolute value
157 /* seg:offs representing the full location value and type */
163 /* Common symbol structure */
165 uint32_t flags
; /* Section/symbol flags */
166 uint32_t size
; /* Size value (for backend) */
167 struct ol_sym
*next
; /* Next symbol in declared order */
168 const char *name
; /* Symbol name */
169 struct ol_symlist syml
; /* Section-local symbol list */
170 struct ol_symlist symg
; /* Section-local global symbol list */
171 struct ol_loc p
; /* Symbol position ("where") */
172 struct ol_loc v
; /* Symbol value ("what") */
179 void ol_cleanup(void);
181 /* Convert offs:seg to a location structure */
183 ol_mkloc(struct ol_loc
*loc
, int64_t offs
, int32_t seg
);
185 /* Get the section or external symbol from a struct ol_seg */
186 static inline O_Section
*seg_sect(struct ol_seg
*seg
)
188 return (O_Section
*)seg
->s
.sect
;
190 static inline O_Symbol
*seg_xsym(struct ol_seg
*seg
)
192 return (O_Symbol
*)seg
->s
.sym
;
196 * Return a pointer to the symbol structure if and only if a section is
197 * really a symbol of some kind (extern, common...)
199 static inline struct ol_sym
*_seg_extsym(struct ol_sect
*sect
)
201 return (sect
->flags
& OF_SYMBOL
) ? (struct ol_sym
*)sect
: NULL
;
203 static inline O_Symbol
*seg_extsym(O_Section
*sect
)
205 return (O_Symbol
*)_seg_extsym((struct ol_sect
*)sect
);
209 * Find a section or create a new section structure if it does not exist
210 * and allocate it an index value via seg_alloc().
212 extern struct ol_sect
*
213 _ol_get_sect(const char *name
, size_t ssize
, size_t rsize
);
214 static inline O_Section
*ol_get_sect(const char *name
)
216 return (O_Section
*)_ol_get_sect(name
, sizeof(O_Section
), sizeof(O_Reloc
));
219 /* Find a section by name without creating one */
220 extern struct ol_sect
*_ol_sect_by_name(const char *);
221 static inline O_Section
*ol_sect_by_name(const char *name
)
223 return (O_Section
*)_ol_sect_by_name(name
);
226 /* Find a section or external symbol by index; NULL if not valid */
227 extern struct ol_sect
*_ol_sect_by_index(int32_t index
);
228 static inline O_Section
*ol_sect_by_index(int32_t index
)
230 return (O_Section
*)_ol_sect_by_index(index
);
233 /* Global list of sections (not including external symbols) */
234 extern struct ol_sect
*_ol_sect_list
;
235 static inline O_Section
*ol_sect_list(void)
237 return (O_Section
*)_ol_sect_list
;
240 /* Count of sections (not including external symbols) */
241 extern uint64_t _ol_nsects
;
242 static inline uint64_t ol_nsects(void)
248 * Start a new subsection for the given section. At the moment, once a
249 * subsection has been created, it is not possible to revert to an
250 * earlier subsection. ol_sect_by_index() will return the main section
251 * structure. Returns the new section index. This is used to prevent
252 * the front end from optimizing across subsection boundaries.
254 extern int32_t _ol_new_subsection(struct ol_sect
*sect
);
255 static inline int32_t ol_new_subsection(O_Section
*sect
)
257 return _ol_new_subsection((struct ol_sect
*)sect
);
261 * Create a new symbol. If this symbol is OS_OFFS, add it to the relevant
262 * section, too. If the symbol already exists, return NULL; this is
263 * different from ol_get_section() as a single section may be invoked
264 * many times. On the contrary, the front end will prevent a single symbol
265 * from being defined more than once.
267 * If flags has OF_GLOBAL set, add it to the global symbol hash for the
268 * containing section. If flags has OF_IMPSEC set, allocate a segment
269 * index for it via seg_alloc() and add it to the section by index list.
271 extern struct ol_sym
*_ol_new_sym(const char *name
, const struct ol_loc
*v
,
272 uint32_t flags
, size_t size
);
273 static inline O_Symbol
*ol_new_sym(const char *name
, const struct ol_loc
*v
,
276 return (O_Symbol
*)_ol_new_sym(name
, v
, flags
, sizeof(O_Symbol
));
279 /* Find a symbol by name in the global namespace */
280 extern struct ol_sym
*_ol_sym_by_name(const char *name
);
281 static inline O_Symbol
*ol_sym_by_name(const char *name
)
283 return (O_Symbol
*)_ol_sym_by_name(name
);
287 * Find a symbol by address in a specific section. If no symbol is defined
288 * at that exact address, return the immediately previously defined one.
289 * If global is set, then only return global symbols.
291 extern struct ol_sym
*_ol_sym_by_address(struct ol_sect
*sect
, int64_t addr
,
293 static inline O_Symbol
*ol_sym_by_address(O_Section
*sect
, int64_t addr
,
296 return (O_Symbol
*)_ol_sym_by_address((struct ol_sect
*)sect
, addr
, global
);
299 /* Global list of symbols */
300 extern struct ol_sym
*_ol_sym_list
;
301 static inline O_Symbol
*ol_sym_list(void)
303 return (O_Symbol
*)_ol_sym_list
;
306 /* Global count of symbols */
307 extern uint64_t _ol_nsyms
;
308 static inline uint64_t ol_nsyms(void)
313 #endif /* NASM_OUTLIB_H */