/* ----------------------------------------------------------------------- * * * Copyright 1996-2017 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. * * ----------------------------------------------------------------------- */ /* * outbin.c output routines for the Netwide Assembler to produce * flat-form binary files */ /* This is the extended version of NASM's original binary output * format. It is backward compatible with the original BIN format, * and contains support for multiple sections and advanced section * ordering. * * Feature summary: * * - Users can create an arbitrary number of sections; they are not * limited to just ".text", ".data", and ".bss". * * - Sections can be either progbits or nobits type. * * - You can specify that they be aligned at a certian boundary * following the previous section ("align="), or positioned at an * arbitrary byte-granular location ("start="). * * - You can specify a "virtual" start address for a section, which * will be used for the calculation for all address references * with respect to that section ("vstart="). * * - The ORG directive, as well as the section/segment directive * arguments ("align=", "start=", "vstart="), can take a critical * expression as their value. For example: "align=(1 << 12)". * * - You can generate map files using the 'map' directive. * */ /* Uncomment the following define if you want sections to adapt * their progbits/nobits state depending on what type of * instructions are issued, rather than defaulting to progbits. * Note that this behavior violates the specification. #define ABIN_SMART_ADAPT */ #include "compiler.h" #include "nctype.h" #include "nasm.h" #include "nasmlib.h" #include "error.h" #include "saa.h" #include "stdscan.h" #include "labels.h" #include "eval.h" #include "outform.h" #include "outlib.h" #ifdef OF_BIN static FILE *rf = …; static void (*do_output)(void); /* Section flags keep track of which attributes the user has defined. */ #define START_DEFINED … #define ALIGN_DEFINED … #define FOLLOWS_DEFINED … #define VSTART_DEFINED … #define VALIGN_DEFINED … #define VFOLLOWS_DEFINED … #define TYPE_DEFINED … #define TYPE_PROGBITS … #define TYPE_NOBITS … /* This struct is used to keep track of symbols for map-file generation. */ static struct bin_label { … } *no_seg_labels, **nsl_tail; static struct Section { … } *sections, *last_section; static struct Reloc { … } *relocs, **reloctail; static uint64_t origin; static int origin_defined; /* Stuff we need for map-file generation. */ #define MAP_ORIGIN … #define MAP_SUMMARY … #define MAP_SECTIONS … #define MAP_SYMBOLS … static int map_control = …; extern macros_t bin_stdmac[]; static void add_reloc(struct Section *s, int32_t bytes, int32_t secref, int32_t secrel) { … } static struct Section *find_section_by_name(const char *name) { … } static struct Section *find_section_by_index(int32_t index) { … } static struct Section *create_section(char *name) { … } static void bin_cleanup(void) { … } static void bin_out(int32_t segto, const void *data, enum out_type type, uint64_t size, int32_t segment, int32_t wrt) { … } static void bin_deflabel(char *name, int32_t segment, int64_t offset, int is_global, char *special) { … } /* These constants and the following function are used * by bin_secname() to parse attribute assignments. */ enum { … }; static int bin_read_attribute(char **line, int *attribute, uint64_t *value) { … } static void bin_sectalign(int32_t seg, unsigned int value) { … } static void bin_assign_attributes(struct Section *sec, char *astring) { … } static void bin_define_section_labels(void) { … } static int32_t bin_secname(char *name, int *bits) { … } static enum directive_result bin_directive(enum directive directive, char *args) { … } const struct ofmt of_bin, of_ith, of_srec; static void binfmt_init(void); static void do_output_bin(void); static void do_output_ith(void); static void do_output_srec(void); static void bin_init(void) { … } static void ith_init(void) { … } static void srec_init(void) { … } static void binfmt_init(void) { … } /* Generate binary file output */ static void do_output_bin(void) { … } /* Generate Intel hex file output */ static void write_ith_record(unsigned int len, uint16_t addr, uint8_t type, void *data) { … } static void do_output_ith(void) { … } /* Generate Motorola S-records */ static void write_srecord(unsigned int len, unsigned int alen, uint32_t addr, uint8_t type, void *data) { … } static void do_output_srec(void) { … } const struct ofmt of_bin = …; const struct ofmt of_ith = …; const struct ofmt of_srec = …; #endif /* #ifdef OF_BIN */