chromium/third_party/nasm/output/outobj.c

/* ----------------------------------------------------------------------- *
 *
 *   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.
 *
 * ----------------------------------------------------------------------- */

/*
 * outobj.c	output routines for the Netwide Assembler to produce
 *		.OBJ object files
 */

#include "compiler.h"

#include <ctype.h>              /* For toupper() */
#include "nctype.h"

#include "nasm.h"
#include "nasmlib.h"
#include "error.h"
#include "stdscan.h"
#include "eval.h"
#include "ver.h"

#include "outform.h"
#include "outlib.h"

#ifdef OF_OBJ

/*
 * outobj.c is divided into two sections.  The first section is low level
 * routines for creating obj records;  It has nearly zero NASM specific
 * code.  The second section is high level routines for processing calls and
 * data structures from the rest of NASM into obj format.
 *
 * It should be easy (though not zero work) to lift the first section out for
 * use as an obj file writer for some other assembler or compiler.
 */

/*
 * These routines are built around the ObjRecord data struture.  An ObjRecord
 * holds an object file record that may be under construction or complete.
 *
 * A major function of these routines is to support continuation of an obj
 * record into the next record when the maximum record size is exceeded.  The
 * high level code does not need to worry about where the record breaks occur.
 * It does need to do some minor extra steps to make the automatic continuation
 * work.  Those steps may be skipped for records where the high level knows no
 * continuation could be required.
 *
 * 1) An ObjRecord is allocated and cleared by obj_new, or an existing ObjRecord
 *    is cleared by obj_clear.
 *
 * 2) The caller should fill in .type.
 *
 * 3) If the record is continuable and there is processing that must be done at
 *    the start of each record then the caller should fill in .ori with the
 *    address of the record initializer routine.
 *
 * 4) If the record is continuable and it should be saved (rather than emitted
 *    immediately) as each record is done, the caller should set .up to be a
 *    pointer to a location in which the caller keeps the master pointer to the
 *    ObjRecord.  When the record is continued, the obj_bump routine will then
 *    allocate a new ObjRecord structure and update the master pointer.
 *
 * 5) If the .ori field was used then the caller should fill in the .parm with
 *    any data required by the initializer.
 *
 * 6) The caller uses the routines: obj_byte, obj_word, obj_rword, obj_dword,
 *    obj_x, obj_index, obj_value and obj_name to fill in the various kinds of
 *    data required for this record.
 *
 * 7) If the record is continuable, the caller should call obj_commit at each
 *    point where breaking the record is permitted.
 *
 * 8) To write out the record, the caller should call obj_emit2.  If the
 *    caller has called obj_commit for all data written then he can get slightly
 *    faster code by calling obj_emit instead of obj_emit2.
 *
 * Most of these routines return an ObjRecord pointer.  This will be the input
 * pointer most of the time and will be the new location if the ObjRecord
 * moved as a result of the call.  The caller may ignore the return value in
 * three cases:  It is a "Never Reallocates" routine;  or  The caller knows
 * continuation is not possible;  or  The caller uses the master pointer for the
 * next operation.
 */

#define RECORD_MAX
#define OBJ_PARMS

#define FIX_08_LOW
#define FIX_16_OFFSET
#define FIX_16_SELECTOR
#define FIX_32_POINTER
#define FIX_08_HIGH
#define FIX_32_OFFSET
#define FIX_48_POINTER

enum RecordID {};

enum ComentID {};

ObjRecord;
ORI;

struct ObjRecord {};

static void obj_fwrite(ObjRecord * orp);
static void ori_ledata(ObjRecord * orp);
static void ori_pubdef(ObjRecord * orp);
static void ori_null(ObjRecord * orp);
static ObjRecord *obj_commit(ObjRecord * orp);

static bool obj_uppercase;       /* Flag: all names in uppercase */
static bool obj_use32;           /* Flag: at least one segment is 32-bit */
static bool obj_nodepend;        /* Flag: don't emit file dependencies */

/*
 * Clear an ObjRecord structure.  (Never reallocates).
 * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
 */
static ObjRecord *obj_clear(ObjRecord * orp)
{}

/*
 * Emit an ObjRecord structure.  (Never reallocates).
 * The record is written out preceeded (recursively) by its previous part (if
 * any) and followed (recursively) by its child (if any).
 * The previous part and the child are freed.  The main ObjRecord is cleared,
 * not freed.
 */
static ObjRecord *obj_emit(ObjRecord * orp)
{}

/*
 * Commit and Emit a record.  (Never reallocates).
 */
static ObjRecord *obj_emit2(ObjRecord * orp)
{}

/*
 * Allocate and clear a new ObjRecord;  Also sets .ori to ori_null
 */
static ObjRecord *obj_new(void)
{}

/*
 * Advance to the next record because the existing one is full or its x_size
 * is incompatible.
 * Any uncommited data is moved into the next record.
 */
static ObjRecord *obj_bump(ObjRecord * orp)
{}

/*
 * Advance to the next record if necessary to allow the next field to fit.
 */
static ObjRecord *obj_check(ObjRecord * orp, int size)
{}

/*
 * All data written so far is commited to the current record (won't be moved to
 * the next record in case of continuation).
 */
static ObjRecord *obj_commit(ObjRecord * orp)
{}

/*
 * Write a byte
 */
static ObjRecord *obj_byte(ObjRecord * orp, uint8_t val)
{}

/*
 * Write a word
 */
static ObjRecord *obj_word(ObjRecord * orp, unsigned int val)
{}

/*
 * Write a reversed word
 */
static ObjRecord *obj_rword(ObjRecord * orp, unsigned int val)
{}

/*
 * Write a dword
 */
static ObjRecord *obj_dword(ObjRecord * orp, uint32_t val)
{}

/*
 * All fields of "size x" in one obj record must be the same size (either 16
 * bits or 32 bits).  There is a one bit flag in each record which specifies
 * which.
 * This routine is used to force the current record to have the desired
 * x_size.  x_size is normally automatic (using obj_x), so that this
 * routine should be used outside obj_x, only to provide compatibility with
 * linkers that have bugs in their processing of the size bit.
 */

static ObjRecord *obj_force(ObjRecord * orp, int x)
{}

/*
 * This routine writes a field of size x.  The caller does not need to worry at
 * all about whether 16-bits or 32-bits are required.
 */
static ObjRecord *obj_x(ObjRecord * orp, uint32_t val)
{}

/*
 * Writes an index
 */
static ObjRecord *obj_index(ObjRecord * orp, unsigned int val)
{}

/*
 * Writes a variable length value
 */
static ObjRecord *obj_value(ObjRecord * orp, uint32_t val)
{}

/*
 * Writes a counted string
 */
static ObjRecord *obj_name(ObjRecord * orp, const char *name)
{}

/*
 * Initializer for an LEDATA record.
 * parm[0] = offset
 * parm[1] = segment index
 * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
 * represent the offset that would be required if the record were split at the
 * last commit point.
 * parm[2] is a copy of parm[0] as it was when the current record was initted.
 */
static void ori_ledata(ObjRecord * orp)
{}

/*
 * Initializer for a PUBDEF record.
 * parm[0] = group index
 * parm[1] = segment index
 * parm[2] = frame (only used when both indexes are zero)
 */
static void ori_pubdef(ObjRecord * orp)
{}

/*
 * Initializer for a LINNUM record.
 * parm[0] = group index
 * parm[1] = segment index
 */
static void ori_linnum(ObjRecord * orp)
{}

/*
 * Initializer for a local vars record.
 */
static void ori_local(ObjRecord * orp)
{}

/*
 * Null initializer for records that continue without any header info
 */
static void ori_null(ObjRecord * orp)
{}

/*
 * This concludes the low level section of outobj.c
 */

static char obj_infile[FILENAME_MAX];

static int32_t first_seg;
static bool any_segs;
static int passtwo;
static int arrindex;

#define GROUP_MAX
#define EXT_BLKSIZ

struct Segment;                 /* need to know these structs exist */
struct Group;

struct LineNumber {};

static struct FileName {} *fnhead, **fntail;

static struct Array {} *arrhead, **arrtail;

#define ARRAYBOT

static struct Public {} *fpubhead, **fpubtail, *last_defined;

static struct External {} *exthead, **exttail, *dws;

static int externals;

static struct ExtBack {} *ebhead, **ebtail;

static struct Segment {} *seghead, **segtail, *obj_seg_needs_update;

static struct Group {} *grphead, **grptail, *obj_grp_needs_update;

static struct ImpDef {} *imphead, **imptail;

static struct ExpDef {} *exphead, **exptail;

#define EXPDEF_FLAG_ORDINAL
#define EXPDEF_FLAG_RESIDENT
#define EXPDEF_FLAG_NODATA
#define EXPDEF_MASK_PARMCNT

static int32_t obj_entry_seg, obj_entry_ofs;

const struct ofmt of_obj;
static const struct dfmt borland_debug_form;

/* The current segment */
static struct Segment *current_seg;

static int32_t obj_segment(char *, int *);
static void obj_write_file(void);
static enum directive_result obj_directive(enum directive, char *);

static void obj_init(void)
{}

static void obj_cleanup(void)
{}

static void obj_ext_set_defwrt(struct External *ext, char *id)
{}

static void obj_deflabel(char *name, int32_t segment,
                         int64_t offset, int is_global, char *special)
{}

/* forward declaration */
static void obj_write_fixup(ObjRecord * orp, int bytes,
                            int segrel, int32_t seg, int32_t wrt,
                            struct Segment *segto);

static void obj_out(int32_t segto, const void *data,
		    enum out_type type, uint64_t size,
                    int32_t segment, int32_t wrt)
{}

static void obj_write_fixup(ObjRecord * orp, int bytes,
                            int segrel, int32_t seg, int32_t wrt,
                            struct Segment *segto)
{}

static int32_t obj_segment(char *name, int *bits)
{}

static enum directive_result
obj_directive(enum directive directive, char *value)
{}

static void obj_sectalign(int32_t seg, unsigned int value)
{}

static int32_t obj_segbase(int32_t segment)
{}

/* Get a file timestamp in MS-DOS format */
static uint32_t obj_file_timestamp(const char *pathname)
{}

static void obj_write_file(void)
{}

static void obj_fwrite(ObjRecord * orp)
{}

static enum directive_result
obj_pragma(const struct pragma *pragma)
{}

extern macros_t obj_stdmac[];

static void dbgbi_init(void)
{}
static void dbgbi_cleanup(void)
{}

static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
{}
static void dbgbi_deflabel(char *name, int32_t segment,
                           int64_t offset, int is_global, char *special)
{}
static void dbgbi_typevalue(int32_t type)
{}
static void dbgbi_output(int output_type, void *param)
{}
static const struct dfmt borland_debug_form =;

static const struct dfmt * const borland_debug_arr[3] =;

static const struct pragma_facility obj_pragma_list[] =;

const struct ofmt of_obj =;
#endif                          /* OF_OBJ */