rbtree: add rb_search_exact()
[nasm.git] / output / outlib.h
blob7f6a7893296d9eb9f35453bcdf995bc569a735fb
1 /* ----------------------------------------------------------------------- *
2 *
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
9 * conditions 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
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 * ----------------------------------------------------------------------- */
34 #ifndef NASM_OUTLIB_H
35 #define NASM_OUTLIB_H
37 #include "compiler.h"
38 #include "nasm.h"
39 #include "error.h"
40 #include "hashtbl.h"
41 #include "saa.h"
42 #include "rbtree.h"
44 uint64_t realsize(enum out_type type, uint64_t size);
46 /* Do-nothing versions of some output routines */
47 enum directive_result
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,
56 int32_t segto);
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!
80 struct ol_sect;
81 struct ol_sym;
83 #ifndef O_Section
84 typedef struct ol_sect O_Section;
85 #endif
86 #ifndef O_Symbol
87 typedef struct ol_sym O_Symbol;
88 #endif
89 #ifndef O_Reloc
90 typedef void * O_Reloc;
91 #endif
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
106 struct ol_sym;
108 struct ol_symlist {
109 struct ol_symlist *next;
110 struct rbtree tree;
112 struct ol_symhead {
113 struct ol_symlist *head, **tail;
114 struct rbtree *tree;
115 uint64_t n;
118 struct ol_sect {
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 */
131 enum ol_seg_type {
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 */
140 union ol_segval {
141 struct ol_sect *sect; /* Section structure */
142 struct ol_sym *sym; /* External symbol structure */
145 struct ol_seg {
146 union ol_segval s;
147 enum ol_seg_type t;
150 * For a section: subsection index
151 * For a metasymbol: virtual segment index
152 * For an absolute symbol: absolute value
154 uint32_t index;
157 /* seg:offs representing the full location value and type */
158 struct ol_loc {
159 int64_t offs;
160 struct ol_seg seg;
163 /* Common symbol structure */
164 struct ol_sym {
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") */
176 * Operations
178 void ol_init(void);
179 void ol_cleanup(void);
181 /* Convert offs:seg to a location structure */
182 extern void
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)
244 return _ol_nsects;
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,
274 uint32_t flags)
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,
292 bool global);
293 static inline O_Symbol *ol_sym_by_address(O_Section *sect, int64_t addr,
294 bool global)
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)
310 return _ol_nsyms;
313 #endif /* NASM_OUTLIB_H */