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

📄 outbin.c

📁 32位汇编编译器nasm源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                      " power of two");
            else {              /* Alignment is already satisfied if the previous
                                 * align value is greater. */
                if ((sec->flags & VALIGN_DEFINED) && (value < sec->valign))
                    value = sec->valign;

                /* Don't allow a conflicting valign value. */
                if ((sec->flags & VSTART_DEFINED)
                    && (sec->vstart & (value - 1)))
                    error(ERR_NONFATAL,
                          "`valign' value conflicts "
                          "with `vstart' address");
                else {
                    sec->valign = value;
                    sec->flags |= VALIGN_DEFINED;
                }
            }
            continue;

            /* Handle start attribute. */
        case ATTRIB_START:
            if (sec->flags & FOLLOWS_DEFINED)
                error(ERR_NONFATAL, "cannot combine `start' and `follows'"
                      " section attributes");
            else if (value < 0)
                error(ERR_NONFATAL, "attempt to specify a negative"
                      " section start address");
            else if ((sec->flags & START_DEFINED) && (value != sec->start))
                error(ERR_NONFATAL, "section start address redefined");
            else {
                sec->start = value;
                sec->flags |= START_DEFINED;
                if (sec->flags & ALIGN_DEFINED) {
                    if (sec->start & (sec->align - 1))
                        error(ERR_NONFATAL, "`start' address conflicts"
                              " with section alignment");
                    sec->flags ^= ALIGN_DEFINED;
                }
            }
            continue;

            /* Handle vstart attribute. */
        case ATTRIB_VSTART:
            if (sec->flags & VFOLLOWS_DEFINED)
                error(ERR_NONFATAL,
                      "cannot combine `vstart' and `vfollows'"
                      " section attributes");
            else if ((sec->flags & VSTART_DEFINED)
                     && (value != sec->vstart))
                error(ERR_NONFATAL,
                      "section virtual start address"
                      " (vstart) redefined");
            else {
                sec->vstart = value;
                sec->flags |= VSTART_DEFINED;
                if (sec->flags & VALIGN_DEFINED) {
                    if (sec->vstart & (sec->valign - 1))
                        error(ERR_NONFATAL, "`vstart' address conflicts"
                              " with `valign' value");
                    sec->flags ^= VALIGN_DEFINED;
                }
            }
            continue;

            /* Handle follows attribute. */
        case ATTRIB_FOLLOWS:
            p = astring;
            astring += strcspn(astring, " \t");
            if (astring == p)
                error(ERR_NONFATAL, "expecting section name for `follows'"
                      " attribute");
            else {
                *(astring++) = '\0';
                if (sec->flags & START_DEFINED)
                    error(ERR_NONFATAL,
                          "cannot combine `start' and `follows'"
                          " section attributes");
                sec->follows = nasm_strdup(p);
                sec->flags |= FOLLOWS_DEFINED;
            }
            continue;

            /* Handle vfollows attribute. */
        case ATTRIB_VFOLLOWS:
            if (sec->flags & VSTART_DEFINED)
                error(ERR_NONFATAL,
                      "cannot combine `vstart' and `vfollows'"
                      " section attributes");
            else {
                p = astring;
                astring += strcspn(astring, " \t");
                if (astring == p)
                    error(ERR_NONFATAL,
                          "expecting section name for `vfollows'"
                          " attribute");
                else {
                    *(astring++) = '\0';
                    sec->vfollows = nasm_strdup(p);
                    sec->flags |= VFOLLOWS_DEFINED;
                }
            }
            continue;
        }
    }
}

static void bin_define_section_labels()
{
    static int labels_defined = 0;
    struct Section *sec;
    char *label_name;
    size_t base_len;

    if (labels_defined)
        return;
    for (sec = sections; sec; sec = sec->next) {
        base_len = strlen(sec->name) + 8;
        label_name = nasm_malloc(base_len + 8);
        strcpy(label_name, "section.");
        strcpy(label_name + 8, sec->name);

        /* section.<name>.start */
        strcpy(label_name + base_len, ".start");
        define_label(label_name, sec->start_index, 0L,
                     NULL, 0, 0, bin_get_ofmt(), error);

        /* section.<name>.vstart */
        strcpy(label_name + base_len, ".vstart");
        define_label(label_name, sec->vstart_index, 0L,
                     NULL, 0, 0, bin_get_ofmt(), error);

        nasm_free(label_name);
    }
    labels_defined = 1;
}

static long bin_secname(char *name, int pass, int *bits)
{
    char *p;
    struct Section *sec;

    /* bin_secname is called with *name = NULL at the start of each
     * pass.  Use this opportunity to establish the default section
     * (default is BITS-16 ".text" segment).
     */
    if (!name) {                /* Reset ORG and section attributes at the start of each pass. */
        origin_defined = 0;
        for (sec = sections; sec; sec = sec->next)
            sec->flags &= ~(START_DEFINED | VSTART_DEFINED |
                            ALIGN_DEFINED | VALIGN_DEFINED);

        /* Define section start and vstart labels. */
        if (format_mode && (pass != 1))
            bin_define_section_labels();

        /* Establish the default (.text) section. */
        *bits = 16;
        sec = find_section_by_name(".text");
        sec->flags |= TYPE_DEFINED | TYPE_PROGBITS;
        current_section = sec->vstart_index;
        return current_section;
    }

    /* Attempt to find the requested section.  If it does not
     * exist, create it. */
    p = name;
    while (*p && !isspace(*p))
        p++;
    if (*p)
        *p++ = '\0';
    sec = find_section_by_name(name);
    if (!sec) {
        sec = create_section(name);
        if (!strcmp(name, ".data"))
            sec->flags |= TYPE_DEFINED | TYPE_PROGBITS;
        else if (!strcmp(name, ".bss")) {
            sec->flags |= TYPE_DEFINED | TYPE_NOBITS;
            sec->ifollows = NULL;
        } else if (!format_mode) {
            error(ERR_NONFATAL, "section name must be "
                  ".text, .data, or .bss");
            return current_section;
        }
    }

    /* Handle attribute assignments. */
    if (pass != 1)
        bin_assign_attributes(sec, p);

#ifndef ABIN_SMART_ADAPT
    /* The following line disables smart adaptation of
     * PROGBITS/NOBITS section types (it forces sections to
     * default to PROGBITS). */
    if ((pass != 1) && !(sec->flags & TYPE_DEFINED))
        sec->flags |= TYPE_DEFINED | TYPE_PROGBITS;
#endif

    /* Set the current section and return. */
    current_section = sec->vstart_index;
    return current_section;
}

static int bin_directive(char *directive, char *args, int pass)
{
    /* Handle ORG directive */
    if (!nasm_stricmp(directive, "org")) {
        struct tokenval tokval;
        unsigned long value;
        expr *e;

        stdscan_reset();
        stdscan_bufptr = args;
        tokval.t_type = TOKEN_INVALID;
        e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
        if (e) {
            if (!is_really_simple(e))
                error(ERR_NONFATAL, "org value must be a critical"
                      " expression");
            else {
                value = reloc_value(e);
                /* Check for ORG redefinition. */
                if (origin_defined && (value != origin))
                    error(ERR_NONFATAL, "program origin redefined");
                else {
                    origin = value;
                    origin_defined = 1;
                }
            }
        } else
            error(ERR_NONFATAL, "No or invalid offset specified"
                  " in ORG directive.");
        return 1;
    }

    /* The 'map' directive allows the user to generate section
     * and symbol information to stdout, stderr, or to a file. */
    else if (format_mode && !nasm_stricmp(directive, "map")) {
        char *p;

        if (pass != 1)
            return 1;
        args += strspn(args, " \t");
        while (*args) {
            p = args;
            args += strcspn(args, " \t");
            if (*args != '\0')
                *(args++) = '\0';
            if (!nasm_stricmp(p, "all"))
                map_control |=
                    MAP_ORIGIN | MAP_SUMMARY | MAP_SECTIONS | MAP_SYMBOLS;
            else if (!nasm_stricmp(p, "brief"))
                map_control |= MAP_ORIGIN | MAP_SUMMARY;
            else if (!nasm_stricmp(p, "sections"))
                map_control |= MAP_ORIGIN | MAP_SUMMARY | MAP_SECTIONS;
            else if (!nasm_stricmp(p, "segments"))
                map_control |= MAP_ORIGIN | MAP_SUMMARY | MAP_SECTIONS;
            else if (!nasm_stricmp(p, "symbols"))
                map_control |= MAP_SYMBOLS;
            else if (!rf) {
                if (!nasm_stricmp(p, "stdout"))
                    rf = stdout;
                else if (!nasm_stricmp(p, "stderr"))
                    rf = stderr;
                else {          /* Must be a filename. */
                    rf = fopen(p, "wt");
                    if (!rf) {
                        error(ERR_WARNING, "unable to open map file `%s'",
                              p);
                        map_control = 0;
                        return 1;
                    }
                }
            } else
                error(ERR_WARNING, "map file already specified");
        }
        if (map_control == 0)
            map_control |= MAP_ORIGIN | MAP_SUMMARY;
        if (!rf)
            rf = stdout;
        return 1;
    }
    return 0;
}

static void bin_filename(char *inname, char *outname, efunc error)
{
    standard_extension(inname, outname, "", error);
    infile = inname;
    outfile = outname;
}

static long bin_segbase(long segment)
{
    return segment;
}

static int bin_set_info(enum geninfo type, char **val)
{
    return 0;
}

static void bin_init(FILE * afp, efunc errfunc, ldfunc ldef, evalfunc eval)
{
    fp = afp;
    error = errfunc;

    (void)eval;                 /* Don't warn that this parameter is unused. */
    (void)ldef;                 /* Placate optimizers. */

    relocs = NULL;
    reloctail = &relocs;
    origin_defined = 0;
    no_seg_labels = NULL;
    nsl_tail = &no_seg_labels;
    format_mode = 1;            /* Extended bin format
                                 * (set this to zero for old bin format). */

    /* Create default section (.text). */
    sections = last_section = nasm_malloc(sizeof(struct Section));
    last_section->next = NULL;
    last_section->name = nasm_strdup(".text");
    last_section->contents = saa_init(1L);
    last_section->follows = last_section->vfollows = 0;
    last_section->ifollows = NULL;
    last_section->length = 0;
    last_section->flags = TYPE_DEFINED | TYPE_PROGBITS;
    last_section->labels = NULL;
    last_section->labels_end = &(last_section->labels);
    last_section->start_index = seg_alloc();
    last_section->vstart_index = current_section = seg_alloc();
}

struct ofmt of_bin = {
    "flat-form binary files (e.g. DOS .COM, .SYS)",
    "bin",
    NULL,
    null_debug_arr,
    &null_debug_form,
    bin_stdmac,
    bin_init,
    bin_set_info,
    bin_out,
    bin_deflabel,
    bin_secname,
    bin_segbase,
    bin_directive,
    bin_filename,
    bin_cleanup
};

/* This is needed for bin_define_section_labels() */
struct ofmt *bin_get_ofmt()
{
    return &of_bin;
}

#endif                          /* #ifdef OF_BIN */

⌨️ 快捷键说明

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