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

📄 outbin.c

📁 32位汇编编译器nasm源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        nasm_free(l);
    }

    /* Free relocation structures. */
    while (relocs) {
        r = relocs->next;
        nasm_free(relocs);
        relocs = r;
    }
}

static void bin_out(long segto, const void *data, unsigned long type,
                    long segment, long wrt)
{
    unsigned char *p, mydata[4];
    struct Section *s;
    long realbytes;

    if (wrt != NO_SEG) {
        wrt = NO_SEG;           /* continue to do _something_ */
        error(ERR_NONFATAL, "WRT not supported by binary output format");
    }

    /* Handle absolute-assembly (structure definitions). */
    if (segto == NO_SEG) {
        if ((type & OUT_TYPMASK) != OUT_RESERVE)
            error(ERR_NONFATAL, "attempt to assemble code in"
                  " [ABSOLUTE] space");
        return;
    }

    /* Find the segment we are targeting. */
    s = find_section_by_index(segto);
    if (!s)
        error(ERR_PANIC, "code directed to nonexistent segment?");

    /* "Smart" section-type adaptation code. */
    if (!(s->flags & TYPE_DEFINED)) {
        if ((type & OUT_TYPMASK) == OUT_RESERVE)
            s->flags |= TYPE_DEFINED | TYPE_NOBITS;
        else
            s->flags |= TYPE_DEFINED | TYPE_PROGBITS;
    }

    if ((s->flags & TYPE_NOBITS) && ((type & OUT_TYPMASK) != OUT_RESERVE))
        error(ERR_WARNING, "attempt to initialise memory in a"
              " nobits section: ignored");

    if ((type & OUT_TYPMASK) == OUT_ADDRESS) {
        if (segment != NO_SEG && !find_section_by_index(segment)) {
            if (segment % 2)
                error(ERR_NONFATAL, "binary output format does not support"
                      " segment base references");
            else
                error(ERR_NONFATAL, "binary output format does not support"
                      " external references");
            segment = NO_SEG;
        }
        if (s->flags & TYPE_PROGBITS) {
            if (segment != NO_SEG)
                add_reloc(s, type & OUT_SIZMASK, segment, -1L);
            p = mydata;
            if ((type & OUT_SIZMASK) == 4)
                WRITELONG(p, *(long *)data);
            else
                WRITESHORT(p, *(long *)data);
            saa_wbytes(s->contents, mydata, type & OUT_SIZMASK);
        }
        s->length += type & OUT_SIZMASK;
    } else if ((type & OUT_TYPMASK) == OUT_RAWDATA) {
        type &= OUT_SIZMASK;
        if (s->flags & TYPE_PROGBITS)
            saa_wbytes(s->contents, data, type);
        s->length += type;
    } else if ((type & OUT_TYPMASK) == OUT_RESERVE) {
        type &= OUT_SIZMASK;
        if (s->flags & TYPE_PROGBITS) {
            error(ERR_WARNING, "uninitialised space declared in"
                  " %s section: zeroing", s->name);
            saa_wbytes(s->contents, NULL, type);
        }
        s->length += type;
    } else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||
               (type & OUT_TYPMASK) == OUT_REL4ADR) {
        realbytes = ((type & OUT_TYPMASK) == OUT_REL4ADR ? 4 : 2);
        if (segment != NO_SEG && !find_section_by_index(segment)) {
            if (segment % 2)
                error(ERR_NONFATAL, "binary output format does not support"
                      " segment base references");
            else
                error(ERR_NONFATAL, "binary output format does not support"
                      " external references");
            segment = NO_SEG;
        }
        if (s->flags & TYPE_PROGBITS) {
            add_reloc(s, realbytes, segment, segto);
            p = mydata;
            if (realbytes == 4)
                WRITELONG(p, *(long *)data - realbytes - s->length);
            else
                WRITESHORT(p, *(long *)data - realbytes - s->length);
            saa_wbytes(s->contents, mydata, realbytes);
        }
        s->length += realbytes;
    }
}

static void bin_deflabel(char *name, long segment, long offset,
                         int is_global, char *special)
{
    (void)segment;              /* Don't warn that this parameter is unused */
    (void)offset;               /* Don't warn that this parameter is unused */

    if (special)
        error(ERR_NONFATAL, "binary format does not support any"
              " special symbol types");
    else if (name[0] == '.' && name[1] == '.' && name[2] != '@')
        error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
    else if (is_global == 2)
        error(ERR_NONFATAL, "binary output format does not support common"
              " variables");
    else {
        struct Section *s;
        struct bin_label ***ltp;

        /* Remember label definition so we can look it up later when
         * creating the map file. */
        s = find_section_by_index(segment);
        if (s)
            ltp = &(s->labels_end);
        else
            ltp = &nsl_tail;
        (**ltp) = nasm_malloc(sizeof(struct bin_label));
        (**ltp)->name = name;
        (**ltp)->next = NULL;
        *ltp = &((**ltp)->next);
    }

}

/* These constants and the following function are used
 * by bin_secname() to parse attribute assignments. */

enum { ATTRIB_START, ATTRIB_ALIGN, ATTRIB_FOLLOWS,
    ATTRIB_VSTART, ATTRIB_VALIGN, ATTRIB_VFOLLOWS,
    ATTRIB_NOBITS, ATTRIB_PROGBITS
};

static int bin_read_attribute(char **line, int *attribute,
                              unsigned long *value)
{
    expr *e;
    int attrib_name_size;
    struct tokenval tokval;
    char *exp;

    /* Skip whitespace. */
    while (**line && isspace(**line))
        (*line)++;
    if (!**line)
        return 0;

    /* Figure out what attribute we're reading. */
    if (!nasm_strnicmp(*line, "align=", 6)) {
        *attribute = ATTRIB_ALIGN;
        attrib_name_size = 6;
    } else if (format_mode) {
        if (!nasm_strnicmp(*line, "start=", 6)) {
            *attribute = ATTRIB_START;
            attrib_name_size = 6;
        } else if (!nasm_strnicmp(*line, "follows=", 8)) {
            *attribute = ATTRIB_FOLLOWS;
            *line += 8;
            return 1;
        } else if (!nasm_strnicmp(*line, "vstart=", 7)) {
            *attribute = ATTRIB_VSTART;
            attrib_name_size = 7;
        } else if (!nasm_strnicmp(*line, "valign=", 7)) {
            *attribute = ATTRIB_VALIGN;
            attrib_name_size = 7;
        } else if (!nasm_strnicmp(*line, "vfollows=", 9)) {
            *attribute = ATTRIB_VFOLLOWS;
            *line += 9;
            return 1;
        } else if (!nasm_strnicmp(*line, "nobits", 6) &&
                   (isspace((*line)[6]) || ((*line)[6] == '\0'))) {
            *attribute = ATTRIB_NOBITS;
            *line += 6;
            return 1;
        } else if (!nasm_strnicmp(*line, "progbits", 8) &&
                   (isspace((*line)[8]) || ((*line)[8] == '\0'))) {
            *attribute = ATTRIB_PROGBITS;
            *line += 8;
            return 1;
        } else
            return 0;
    } else
        return 0;

    /* Find the end of the expression. */
    if ((*line)[attrib_name_size] != '(') {
        /* Single term (no parenthesis). */
        exp = *line += attrib_name_size;
        while (**line && !isspace(**line))
            (*line)++;
        if (**line) {
            **line = '\0';
            (*line)++;
        }
    } else {
        char c;
        int pcount = 1;

        /* Full expression (delimited by parenthesis) */
        exp = *line += attrib_name_size + 1;
        while (1) {
            (*line) += strcspn(*line, "()'\"");
            if (**line == '(') {
                ++(*line);
                ++pcount;
            }
            if (**line == ')') {
                ++(*line);
                --pcount;
                if (!pcount)
                    break;
            }
            if ((**line == '"') || (**line == '\'')) {
                c = **line;
                while (**line) {
                    ++(*line);
                    if (**line == c)
                        break;
                }
                if (!**line) {
                    error(ERR_NONFATAL,
                          "invalid syntax in `section' directive");
                    return -1;
                }
                ++(*line);
            }
            if (!**line) {
                error(ERR_NONFATAL, "expecting `)'");
                return -1;
            }
        }
        *(*line - 1) = '\0';    /* Terminate the expression. */
    }

    /* Check for no value given. */
    if (!*exp) {
        error(ERR_WARNING, "No value given to attribute in"
              " `section' directive");
        return -1;
    }

    /* Read and evaluate the expression. */
    stdscan_reset();
    stdscan_bufptr = exp;
    tokval.t_type = TOKEN_INVALID;
    e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
    if (e) {
        if (!is_really_simple(e)) {
            error(ERR_NONFATAL, "section attribute value must be"
                  " a critical expression");
            return -1;
        }
    } else {
        error(ERR_NONFATAL, "Invalid attribute value"
              " specified in `section' directive.");
        return -1;
    }
    *value = (unsigned long)reloc_value(e);
    return 1;
}

static void bin_assign_attributes(struct Section *sec, char *astring)
{
    int attribute, check;
    unsigned long value;
    char *p;

    while (1) {                 /* Get the next attribute. */
        check = bin_read_attribute(&astring, &attribute, &value);
        /* Skip bad attribute. */
        if (check == -1)
            continue;
        /* Unknown section attribute, so skip it and warn the user. */
        if (!check) {
            if (!*astring)
                break;          /* End of line. */
            else {
                p = astring;
                while (*astring && !isspace(*astring))
                    astring++;
                if (*astring) {
                    *astring = '\0';
                    astring++;
                }
                error(ERR_WARNING, "ignoring unknown section attribute:"
                      " \"%s\"", p);
            }
            continue;
        }

        switch (attribute) {    /* Handle nobits attribute. */
        case ATTRIB_NOBITS:
            if ((sec->flags & TYPE_DEFINED)
                && (sec->flags & TYPE_PROGBITS))
                error(ERR_NONFATAL,
                      "attempt to change section type"
                      " from progbits to nobits");
            else
                sec->flags |= TYPE_DEFINED | TYPE_NOBITS;
            continue;

            /* Handle progbits attribute. */
        case ATTRIB_PROGBITS:
            if ((sec->flags & TYPE_DEFINED) && (sec->flags & TYPE_NOBITS))
                error(ERR_NONFATAL, "attempt to change section type"
                      " from nobits to progbits");
            else
                sec->flags |= TYPE_DEFINED | TYPE_PROGBITS;
            continue;

            /* Handle align attribute. */
        case ATTRIB_ALIGN:
            if (!format_mode && (!strcmp(sec->name, ".text")))
                error(ERR_NONFATAL, "cannot specify an alignment"
                      " to the .text section");
            else {
                if (!value || ((value - 1) & value))
                    error(ERR_NONFATAL, "argument to `align' is not a"
                          " power of two");
                else {          /* Alignment is already satisfied if the previous
                                 * align value is greater. */
                    if ((sec->flags & ALIGN_DEFINED)
                        && (value < sec->align))
                        value = sec->align;

                    /* Don't allow a conflicting align value. */
                    if ((sec->flags & START_DEFINED)
                        && (sec->start & (value - 1)))
                        error(ERR_NONFATAL,
                              "`align' value conflicts "
                              "with section start address");
                    else {
                        sec->align = value;
                        sec->flags |= ALIGN_DEFINED;
                    }
                }
            }
            continue;

            /* Handle valign attribute. */
        case ATTRIB_VALIGN:
            if (!value || ((value - 1) & value))
                error(ERR_NONFATAL, "argument to `valign' is not a"

⌨️ 快捷键说明

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