⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 outobj.c

📁 nasm的全套源代码,有些我做了些修改,以方便您更方便更容易调试成功,方便学习做编译器
💻 C
📖 第 1 页 / 共 5 页
字号:

/*
 * 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)
{
    obj_index(orp, orp->parm[0]);
    obj_index(orp, orp->parm[1]);
    if (!(orp->parm[0] | orp->parm[1]))
        obj_word(orp, orp->parm[2]);
}

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

/*
 * Initializer for a local vars record.
 */
static void ori_local(ObjRecord * orp)
{
    obj_byte(orp, 0x40);
    obj_byte(orp, dSYM);
}

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

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

static char obj_infile[FILENAME_MAX];

static efunc error;
static evalfunc evaluate;
static ldfunc deflabel;
static FILE *ofp;
static long first_seg;
static int any_segs;
static int passtwo;
static int arrindex;

#define GROUP_MAX 256           /* we won't _realistically_ have more
                                 * than this many segs in a group */
#define EXT_BLKSIZ 256          /* block size for externals list */

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

struct LineNumber {
    struct LineNumber *next;
    struct Segment *segment;
    long offset;
    long lineno;
};

static struct FileName {
    struct FileName *next;
    char *name;
    struct LineNumber *lnhead, **lntail;
    int index;
} *fnhead, **fntail;

static struct Array {
    struct Array *next;
    unsigned size;
    int basetype;
} *arrhead, **arrtail;

#define ARRAYBOT 31             /* magic number  for first array index */

static struct Public {
    struct Public *next;
    char *name;
    long offset;
    long segment;               /* only if it's far-absolute */
    int type;                   /* only for local debug syms */
} *fpubhead, **fpubtail, *last_defined;

static struct External {
    struct External *next;
    char *name;
    long commonsize;
    long commonelem;            /* element size if FAR, else zero */
    int index;                  /* OBJ-file external index */
    enum {
        DEFWRT_NONE,            /* no unusual default-WRT */
        DEFWRT_STRING,          /* a string we don't yet understand */
        DEFWRT_SEGMENT,         /* a segment */
        DEFWRT_GROUP            /* a group */
    } defwrt_type;
    union {
        char *string;
        struct Segment *seg;
        struct Group *grp;
    } defwrt_ptr;
    struct External *next_dws;  /* next with DEFWRT_STRING */
} *exthead, **exttail, *dws;

static int externals;

static struct ExtBack {
    struct ExtBack *next;
    struct External *exts[EXT_BLKSIZ];
} *ebhead, **ebtail;

static struct Segment {
    struct Segment *next;
    long index;                 /* the NASM segment id */
    long obj_index;             /* the OBJ-file segment index */
    struct Group *grp;          /* the group it belongs to */
    unsigned long currentpos;
    long align;                 /* can be SEG_ABS + absolute addr */
    enum {
        CMB_PRIVATE = 0,
        CMB_PUBLIC = 2,
        CMB_STACK = 5,
        CMB_COMMON = 6
    } combine;
    long use32;                 /* is this segment 32-bit? */
    struct Public *pubhead, **pubtail, *lochead, **loctail;
    char *name;
    char *segclass, *overlay;   /* `class' is a C++ keyword :-) */
    ObjRecord *orp;
} *seghead, **segtail, *obj_seg_needs_update;

static struct Group {
    struct Group *next;
    char *name;
    long index;                 /* NASM segment id */
    long obj_index;             /* OBJ-file group index */
    long nentries;              /* number of elements... */
    long nindices;              /* ...and number of index elts... */
    union {
        long index;
        char *name;
    } segs[GROUP_MAX];          /* ...in this */
} *grphead, **grptail, *obj_grp_needs_update;

static struct ImpDef {
    struct ImpDef *next;
    char *extname;
    char *libname;
    unsigned int impindex;
    char *impname;
} *imphead, **imptail;

static struct ExpDef {
    struct ExpDef *next;
    char *intname;
    char *extname;
    unsigned int ordinal;
    int flags;
} *exphead, **exptail;

#define EXPDEF_FLAG_ORDINAL  0x80
#define EXPDEF_FLAG_RESIDENT 0x40
#define EXPDEF_FLAG_NODATA   0x20
#define EXPDEF_MASK_PARMCNT  0x1F

static long obj_entry_seg, obj_entry_ofs;

struct ofmt of_obj;

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

static long obj_segment(char *, int, int *);
static void obj_write_file(int debuginfo);
static int obj_directive(char *, char *, int);

static void obj_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
{
    ofp = fp;
    error = errfunc;
    evaluate = eval;
    deflabel = ldef;
    first_seg = seg_alloc();
    any_segs = FALSE;
    fpubhead = NULL;
    fpubtail = &fpubhead;
    exthead = NULL;
    exttail = &exthead;
    imphead = NULL;
    imptail = &imphead;
    exphead = NULL;
    exptail = &exphead;
    dws = NULL;
    externals = 0;
    ebhead = NULL;
    ebtail = &ebhead;
    seghead = obj_seg_needs_update = NULL;
    segtail = &seghead;
    grphead = obj_grp_needs_update = NULL;
    grptail = &grphead;
    obj_entry_seg = NO_SEG;
    obj_uppercase = FALSE;
    obj_use32 = FALSE;
    passtwo = 0;
    current_seg = NULL;

    of_obj.current_dfmt->init(&of_obj, NULL, fp, errfunc);
}

static int obj_set_info(enum geninfo type, char **val)
{
    (void)type;
    (void)val;

    return 0;
}
static void obj_cleanup(int debuginfo)
{
    obj_write_file(debuginfo);
    of_obj.current_dfmt->cleanup();
    fclose(ofp);
    while (seghead) {
        struct Segment *segtmp = seghead;
        seghead = seghead->next;
        while (segtmp->pubhead) {
            struct Public *pubtmp = segtmp->pubhead;
            segtmp->pubhead = pubtmp->next;
            nasm_free(pubtmp->name);
            nasm_free(pubtmp);
        }
        nasm_free(segtmp->segclass);
        nasm_free(segtmp->overlay);
        nasm_free(segtmp);
    }
    while (fpubhead) {
        struct Public *pubtmp = fpubhead;
        fpubhead = fpubhead->next;
        nasm_free(pubtmp->name);
        nasm_free(pubtmp);
    }
    while (exthead) {
        struct External *exttmp = exthead;
        exthead = exthead->next;
        nasm_free(exttmp);
    }
    while (imphead) {
        struct ImpDef *imptmp = imphead;
        imphead = imphead->next;
        nasm_free(imptmp->extname);
        nasm_free(imptmp->libname);
        nasm_free(imptmp->impname);     /* nasm_free won't mind if it's NULL */
        nasm_free(imptmp);
    }
    while (exphead) {
        struct ExpDef *exptmp = exphead;
        exphead = exphead->next;
        nasm_free(exptmp->extname);
        nasm_free(exptmp->intname);
        nasm_free(exptmp);
    }
    while (ebhead) {
        struct ExtBack *ebtmp = ebhead;
        ebhead = ebhead->next;
        nasm_free(ebtmp);
    }
    while (grphead) {
        struct Group *grptmp = grphead;
        grphead = grphead->next;
        nasm_free(grptmp);
    }
}

static void obj_ext_set_defwrt(struct External *ext, char *id)
{
    struct Segment *seg;
    struct Group *grp;

    for (seg = seghead; seg; seg = seg->next)
        if (!strcmp(seg->name, id)) {
            ext->defwrt_type = DEFWRT_SEGMENT;
            ext->defwrt_ptr.seg = seg;
            nasm_free(id);
            return;
        }

    for (grp = grphead; grp; grp = grp->next)
        if (!strcmp(grp->name, id)) {
            ext->defwrt_type = DEFWRT_GROUP;
            ext->defwrt_ptr.grp = grp;
            nasm_free(id);
            return;
        }

    ext->defwrt_type = DEFWRT_STRING;
    ext->defwrt_ptr.string = id;
    ext->next_dws = dws;
    dws = ext;
}

static void obj_deflabel(char *name, long segment,
                         long offset, int is_global, char *special)
{
    /*
     * We have three cases:
     *
     * (i) `segment' is a segment-base. If so, set the name field
     * for the segment or group structure it refers to, and then
     * return.
     *
     * (ii) `segment' is one of our segments, or a SEG_ABS segment.
     * Save the label position for later output of a PUBDEF record.
     * (Or a MODPUB, if we work out how.)
     *
     * (iii) `segment' is not one of our segments. Save the label
     * position for later output of an EXTDEF, and also store a
     * back-reference so that we can map later references to this
     * segment number to the external index.
     */
    struct External *ext;
    struct ExtBack *eb;
    struct Segment *seg;
    int i;
    int used_special = FALSE;   /* have we used the special text? */

#if defined(DEBUG) && DEBUG>2
    fprintf(stderr,
            " obj_deflabel: %s, seg=%ld, off=%ld, is_global=%d, %s\n",
            name, segment, offset, is_global, special);
#endif

    /*
     * If it's a special-retry from pass two, discard it.
     */
    if (is_global == 3)
        return;

    /*
     * First check for the double-period, signifying something
     * unusual.
     */
    if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
        if (!strcmp(name, "..start")) {
            obj_entry_seg = segment;
            obj_entry_ofs = offset;
            return;
        }
        error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
    }

    /*
     * Case (i):
     */
    if (obj_seg_needs_update) {
        obj_seg_needs_update->name = name;
        return;
    } else if (obj_grp_needs_update) {
        obj_grp_needs_update->name = name;
        return;
    }
    if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
        return;

    if (segment >= SEG_ABS || segment == NO_SEG) {
        /*
         * SEG_ABS subcase of (ii).
         */
        if (is_global) {
            struct Public *pub;

            pub = *fpubtail = nasm_malloc(sizeof(*pub));
            fpubtail = &pub->next;
            pub->next = NULL;
            pub->name = nasm_strdup(name);
            pub->offset = offset;
            pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
        }
        if (special)
            error(ERR_NONFATAL, "OBJ supports no special symbol features"
                  " for this symbol type");
        return;
    }

    /*
     * If `any_segs' is still FALSE, we might need to define a
     * default segment, if they're trying to declare a label in
     * `first_seg'.
     */
    if (!any_segs && segment == first_seg) {
        int tempint;            /* ignored */
        if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
            error(ERR_PANIC, "strange segment conditions in OBJ driver");
    }

    for (seg = seghead; seg && is_global; seg = seg->next)
        if (seg->index == segment) {
            struct Public *loc = nasm_malloc(sizeof(*loc));
            /*
             * Case (ii). Maybe MODPUB someday?
             */
            *seg->pubtail = loc;
            seg->pubtail = &loc->next;
            loc->next = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -