diff options
Diffstat (limited to 'vere/ext/nasm/output/outlib.h')
-rw-r--r-- | vere/ext/nasm/output/outlib.h | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/vere/ext/nasm/output/outlib.h b/vere/ext/nasm/output/outlib.h new file mode 100644 index 0000000..7f6a789 --- /dev/null +++ b/vere/ext/nasm/output/outlib.h @@ -0,0 +1,313 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2020 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#ifndef NASM_OUTLIB_H +#define NASM_OUTLIB_H + +#include "compiler.h" +#include "nasm.h" +#include "error.h" +#include "hashtbl.h" +#include "saa.h" +#include "rbtree.h" + +uint64_t realsize(enum out_type type, uint64_t size); + +/* Do-nothing versions of some output routines */ +enum directive_result +null_directive(enum directive directive, char *value); +void null_sectalign(int32_t seg, unsigned int value); +void null_reset(void); +int32_t null_segbase(int32_t seg); + +/* Do-nothing versions of all the debug routines */ +void null_debug_init(void); +void null_debug_linenum(const char *filename, int32_t linenumber, + int32_t segto); +void null_debug_deflabel(char *name, int32_t segment, int64_t offset, + int is_global, char *special); +void null_debug_directive(const char *directive, const char *params); +void null_debug_typevalue(int32_t type); +void null_debug_output(int type, void *param); +void null_debug_cleanup(void); +extern const struct dfmt * const null_debug_arr[2]; + +/* Wrapper for unported backends */ +void nasm_do_legacy_output(const struct out_data *data); + +/* + * Common routines for tasks that really should migrate into the core. + * This provides a common interface for maintaining sections and symbols, + * and provide quick lookups as well as declared-order sequential walks. + * + * These structures are intended to be embedded at the *top* of a + * backend-specific structure containing additional information. + * + * The tokens O_Section, O_Symbol and O_Reloc are intended to be + * defined as macros by the backend before including this file! + */ + +struct ol_sect; +struct ol_sym; + +#ifndef O_Section +typedef struct ol_sect O_Section; +#endif +#ifndef O_Symbol +typedef struct ol_sym O_Symbol; +#endif +#ifndef O_Reloc +typedef void * O_Reloc; +#endif + +/* Common section structure */ + +/* + * Common flags for sections and symbols; low values reserved for + * backend. Note that both ol_sect and ol_sym begin with a flags + * field, so if a section pointer points to an external symbol instead + * they can be trivially resolved. + */ +#define OF_SYMBOL 0x80000000 +#define OF_GLOBAL 0x40000000 +#define OF_IMPSEC 0x20000000 +#define OF_COMMON 0x10000000 + +struct ol_sym; + +struct ol_symlist { + struct ol_symlist *next; + struct rbtree tree; +}; +struct ol_symhead { + struct ol_symlist *head, **tail; + struct rbtree *tree; + uint64_t n; +}; + +struct ol_sect { + uint32_t flags; /* Section/symbol flags */ + struct ol_sect *next; /* Next section in declared order */ + const char *name; /* Name of section */ + struct ol_symhead syml; /* All symbols in this section */ + struct ol_symhead symg; /* Global symbols in this section */ + struct SAA *data; /* Contents of section */ + struct SAA *reloc; /* Section relocations */ + uint32_t index; /* Primary section index */ + uint32_t subindex; /* Current subsection index */ +}; + +/* Segment reference */ +enum ol_seg_type { + OS_NOSEG = 0, /* Plain number (no segment) */ + OS_SEGREF = 1, /* It is a segment reference */ + OS_ABS = 1, /* Absolute segment reference */ + OS_SECT = 2, /* It is a real section */ + OS_OFFS = OS_SECT, /* Offset reference in section */ + OS_SEG = OS_SECT|OS_SEGREF /* Section reference */ +}; + +union ol_segval { + struct ol_sect *sect; /* Section structure */ + struct ol_sym *sym; /* External symbol structure */ +}; + +struct ol_seg { + union ol_segval s; + enum ol_seg_type t; + + /* + * For a section: subsection index + * For a metasymbol: virtual segment index + * For an absolute symbol: absolute value + */ + uint32_t index; +}; + +/* seg:offs representing the full location value and type */ +struct ol_loc { + int64_t offs; + struct ol_seg seg; +}; + +/* Common symbol structure */ +struct ol_sym { + uint32_t flags; /* Section/symbol flags */ + uint32_t size; /* Size value (for backend) */ + struct ol_sym *next; /* Next symbol in declared order */ + const char *name; /* Symbol name */ + struct ol_symlist syml; /* Section-local symbol list */ + struct ol_symlist symg; /* Section-local global symbol list */ + struct ol_loc p; /* Symbol position ("where") */ + struct ol_loc v; /* Symbol value ("what") */ +}; + +/* + * Operations + */ +void ol_init(void); +void ol_cleanup(void); + +/* Convert offs:seg to a location structure */ +extern void +ol_mkloc(struct ol_loc *loc, int64_t offs, int32_t seg); + +/* Get the section or external symbol from a struct ol_seg */ +static inline O_Section *seg_sect(struct ol_seg *seg) +{ + return (O_Section *)seg->s.sect; +} +static inline O_Symbol *seg_xsym(struct ol_seg *seg) +{ + return (O_Symbol *)seg->s.sym; +} + +/* + * Return a pointer to the symbol structure if and only if a section is + * really a symbol of some kind (extern, common...) + */ +static inline struct ol_sym *_seg_extsym(struct ol_sect *sect) +{ + return (sect->flags & OF_SYMBOL) ? (struct ol_sym *)sect : NULL; +} +static inline O_Symbol *seg_extsym(O_Section *sect) +{ + return (O_Symbol *)_seg_extsym((struct ol_sect *)sect); +} + +/* + * Find a section or create a new section structure if it does not exist + * and allocate it an index value via seg_alloc(). + */ +extern struct ol_sect * +_ol_get_sect(const char *name, size_t ssize, size_t rsize); +static inline O_Section *ol_get_sect(const char *name) +{ + return (O_Section *)_ol_get_sect(name, sizeof(O_Section), sizeof(O_Reloc)); +} + +/* Find a section by name without creating one */ +extern struct ol_sect *_ol_sect_by_name(const char *); +static inline O_Section *ol_sect_by_name(const char *name) +{ + return (O_Section *)_ol_sect_by_name(name); +} + +/* Find a section or external symbol by index; NULL if not valid */ +extern struct ol_sect *_ol_sect_by_index(int32_t index); +static inline O_Section *ol_sect_by_index(int32_t index) +{ + return (O_Section *)_ol_sect_by_index(index); +} + +/* Global list of sections (not including external symbols) */ +extern struct ol_sect *_ol_sect_list; +static inline O_Section *ol_sect_list(void) +{ + return (O_Section *)_ol_sect_list; +} + +/* Count of sections (not including external symbols) */ +extern uint64_t _ol_nsects; +static inline uint64_t ol_nsects(void) +{ + return _ol_nsects; +} + +/* + * Start a new subsection for the given section. At the moment, once a + * subsection has been created, it is not possible to revert to an + * earlier subsection. ol_sect_by_index() will return the main section + * structure. Returns the new section index. This is used to prevent + * the front end from optimizing across subsection boundaries. + */ +extern int32_t _ol_new_subsection(struct ol_sect *sect); +static inline int32_t ol_new_subsection(O_Section *sect) +{ + return _ol_new_subsection((struct ol_sect *)sect); +} + +/* + * Create a new symbol. If this symbol is OS_OFFS, add it to the relevant + * section, too. If the symbol already exists, return NULL; this is + * different from ol_get_section() as a single section may be invoked + * many times. On the contrary, the front end will prevent a single symbol + * from being defined more than once. + * + * If flags has OF_GLOBAL set, add it to the global symbol hash for the + * containing section. If flags has OF_IMPSEC set, allocate a segment + * index for it via seg_alloc() and add it to the section by index list. + */ +extern struct ol_sym *_ol_new_sym(const char *name, const struct ol_loc *v, + uint32_t flags, size_t size); +static inline O_Symbol *ol_new_sym(const char *name, const struct ol_loc *v, + uint32_t flags) +{ + return (O_Symbol *)_ol_new_sym(name, v, flags, sizeof(O_Symbol)); +} + +/* Find a symbol by name in the global namespace */ +extern struct ol_sym *_ol_sym_by_name(const char *name); +static inline O_Symbol *ol_sym_by_name(const char *name) +{ + return (O_Symbol *)_ol_sym_by_name(name); +} + +/* + * Find a symbol by address in a specific section. If no symbol is defined + * at that exact address, return the immediately previously defined one. + * If global is set, then only return global symbols. + */ +extern struct ol_sym *_ol_sym_by_address(struct ol_sect *sect, int64_t addr, + bool global); +static inline O_Symbol *ol_sym_by_address(O_Section *sect, int64_t addr, + bool global) +{ + return (O_Symbol *)_ol_sym_by_address((struct ol_sect *)sect, addr, global); +} + +/* Global list of symbols */ +extern struct ol_sym *_ol_sym_list; +static inline O_Symbol *ol_sym_list(void) +{ + return (O_Symbol *)_ol_sym_list; +} + +/* Global count of symbols */ +extern uint64_t _ol_nsyms; +static inline uint64_t ol_nsyms(void) +{ + return _ol_nsyms; +} + +#endif /* NASM_OUTLIB_H */ |