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

📄 outbin.c

📁 32位汇编编译器nasm源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
             gs && !(gs->flags & START_DEFINED);
             gsp = &gs->next, gs = gs->next) ;
        /* Re-link the group before the target section. */
        *sp = g;
        *gsp = s;
    }

    /* Step 3: Compute start addresses for all progbits sections. */

    /* Make sure we have an origin and a start address for the first section. */
    if (origin_defined)
        switch (sections->flags & (START_DEFINED | ALIGN_DEFINED)) {
        case START_DEFINED | ALIGN_DEFINED:
        case START_DEFINED:
            /* Make sure this section doesn't begin before the origin. */
            if (sections->start < origin)
                error(ERR_FATAL, "section %s begins"
                      " before program origin", sections->name);
            break;
        case ALIGN_DEFINED:
            sections->start = ((origin + sections->align - 1) &
                               ~(sections->align - 1));
            break;
        case 0:
            sections->start = origin;
    } else {
        if (!(sections->flags & START_DEFINED))
            sections->start = 0;
        origin = sections->start;
    }
    sections->flags |= START_DEFINED;

    /* Make sure each section has an explicit start address.  If it
     * doesn't, then compute one based its alignment and the end of
     * the previous section. */
    for (pend = sections->start, g = s = sections; g; g = g->next) {    /* Find the next section that could cause an overlap situation
                                                                         * (has a defined start address, and is not zero length). */
        if (g == s)
            for (s = g->next;
                 s && ((s->length == 0) || !(s->flags & START_DEFINED));
                 s = s->next) ;
        /* Compute the start address of this section, if necessary. */
        if (!(g->flags & START_DEFINED)) {      /* Default to an alignment of 4 if unspecified. */
            if (!(g->flags & ALIGN_DEFINED)) {
                g->align = 4;
                g->flags |= ALIGN_DEFINED;
            }
            /* Set the section start address. */
            g->start = (pend + g->align - 1) & ~(g->align - 1);
            g->flags |= START_DEFINED;
        }
        /* Ugly special case for progbits sections' virtual attributes:
         *   If there is a defined valign, but no vstart and no vfollows, then
         *   we valign after the previous progbits section.  This case doesn't
         *   really make much sense for progbits sections with a defined start
         *   address, but it is possible and we must do *something*.
         * Not-so-ugly special case:
         *   If a progbits section has no virtual attributes, we set the
         *   vstart equal to the start address.  */
        if (!(g->flags & (VSTART_DEFINED | VFOLLOWS_DEFINED))) {
            if (g->flags & VALIGN_DEFINED)
                g->vstart = (pend + g->valign - 1) & ~(g->valign - 1);
            else
                g->vstart = g->start;
            g->flags |= VSTART_DEFINED;
        }
        /* Ignore zero-length sections. */
        if (g->start < pend)
            continue;
        /* Compute the span of this section. */
        pend = g->start + g->length;
        /* Check for section overlap. */
        if (s) {
            if (g->start > s->start)
                error(ERR_FATAL, "sections %s ~ %s and %s overlap!",
                      gs->name, g->name, s->name);
            if (pend > s->start)
                error(ERR_FATAL, "sections %s and %s overlap!",
                      g->name, s->name);
        }
        /* Remember this section as the latest >0 length section. */
        gs = g;
    }

    /* Step 4: Compute vstart addresses for all sections. */

    /* Attach the nobits sections to the end of the progbits sections. */
    for (s = sections; s->next; s = s->next) ;
    s->next = nobits;
    last_progbits = s;
    /* Scan for sections that don't have a vstart address.  If we find one we'll
     * attempt to compute its vstart.  If we can't compute the vstart, we leave
     * it alone and come back to it in a subsequent scan.  We continue scanning
     * and re-scanning until we've gone one full cycle without computing any
     * vstarts. */
    do {                        /* Do one full scan of the sections list. */
        for (h = 0, g = sections; g; g = g->next) {
            if (g->flags & VSTART_DEFINED)
                continue;
            /* Find the section that this one virtually follows.  */
            if (g->flags & VFOLLOWS_DEFINED) {
                for (s = sections; s && strcmp(g->vfollows, s->name);
                     s = s->next) ;
                if (!s)
                    error(ERR_FATAL,
                          "section %s vfollows unknown section (%s)",
                          g->name, g->vfollows);
            } else if (g->ifollows != NULL)
                for (s = sections; s && (s != g->ifollows); s = s->next) ;
            /* The .bss section is the only one with ifollows = NULL.  In this case we
             * implicitly follow the last progbits section.  */
            else
                s = last_progbits;

            /* If the section we're following has a vstart, we can proceed. */
            if (s->flags & VSTART_DEFINED) {    /* Default to virtual alignment of four. */
                if (!(g->flags & VALIGN_DEFINED)) {
                    g->valign = 4;
                    g->flags |= VALIGN_DEFINED;
                }
                /* Compute the vstart address. */
                g->vstart =
                    (s->vstart + s->length + g->valign - 1) & ~(g->valign -
                                                                1);
                g->flags |= VSTART_DEFINED;
                h++;
                /* Start and vstart mean the same thing for nobits sections. */
                if (g->flags & TYPE_NOBITS)
                    g->start = g->vstart;
            }
        }
    } while (h);

    /* Now check for any circular vfollows references, which will manifest
     * themselves as sections without a defined vstart. */
    for (h = 0, s = sections; s; s = s->next) {
        if (!(s->flags & VSTART_DEFINED)) {     /* Non-fatal errors after assembly has completed are generally a
                                                 * no-no, but we'll throw a fatal one eventually so it's ok.  */
            error(ERR_NONFATAL, "cannot compute vstart for section %s",
                  s->name);
            h++;
        }
    }
    if (h)
        error(ERR_FATAL, "circular vfollows path detected");

#ifdef DEBUG
    fprintf(stdout,
            "bin_cleanup: Confirm final section order for output file:\n");
    for (h = 0, s = sections; s && (s->flags & TYPE_PROGBITS);
         h++, s = s->next)
        fprintf(stdout, "%i. %s\n", h, s->name);
#endif

    /* Step 5: Apply relocations. */

    /* Prepare the sections for relocating. */
    for (s = sections; s; s = s->next)
        saa_rewind(s->contents);
    /* Apply relocations. */
    for (r = relocs; r; r = r->next) {
        unsigned char *p, *q, mydata[4];
        long l;

        saa_fread(r->target->contents, r->posn, mydata, r->bytes);
        p = q = mydata;
        l = *p++;

        if (r->bytes > 1) {
            l += ((long)*p++) << 8;
            if (r->bytes == 4) {
                l += ((long)*p++) << 16;
                l += ((long)*p++) << 24;
            }
        }

        s = find_section_by_index(r->secref);
        if (s) {
            if (r->secref == s->start_index)
                l += s->start;
            else
                l += s->vstart;
        }
        s = find_section_by_index(r->secrel);
        if (s) {
            if (r->secrel == s->start_index)
                l -= s->start;
            else
                l -= s->vstart;
        }

        if (r->bytes == 4)
            WRITELONG(q, l);
        else if (r->bytes == 2)
            WRITESHORT(q, l);
        else
            *q++ = (unsigned char)(l & 0xFF);
        saa_fwrite(r->target->contents, r->posn, mydata, r->bytes);
    }

    /* Step 6: Write the section data to the output file. */

    /* Write the progbits sections to the output file. */
    for (pend = origin, s = sections; s && (s->flags & TYPE_PROGBITS); s = s->next) {   /* Skip zero-length sections. */
        if (s->length == 0)
            continue;
        /* Pad the space between sections. */
        for (h = s->start - pend; h; h--)
            fputc('\0', fp);
        /* Write the section to the output file. */
        if (s->length > 0)
            saa_fpwrite(s->contents, fp);
        pend = s->start + s->length;
    }
    /* Done writing the file, so close it. */
    fclose(fp);

    /* Step 7: Generate the map file. */

    if (map_control) {
        const char *not_defined = { "not defined" };

        /* Display input and output file names. */
        fprintf(rf, "\n- NASM Map file ");
        for (h = 63; h; h--)
            fputc('-', rf);
        fprintf(rf, "\n\nSource file:  %s\nOutput file:  %s\n\n",
                infile, outfile);

        if (map_control & MAP_ORIGIN) { /* Display program origin. */
            fprintf(rf, "-- Program origin ");
            for (h = 61; h; h--)
                fputc('-', rf);
            fprintf(rf, "\n\n%08lX\n\n", origin);
        }
        /* Display sections summary. */
        if (map_control & MAP_SUMMARY) {
            fprintf(rf, "-- Sections (summary) ");
            for (h = 57; h; h--)
                fputc('-', rf);
            fprintf(rf, "\n\nVstart    Start     Stop      "
                    "Length    Class     Name\n");
            for (s = sections; s; s = s->next) {
                fprintf(rf, "%08lX  %08lX  %08lX  %08lX  ",
                        s->vstart, s->start, s->start + s->length,
                        s->length);
                if (s->flags & TYPE_PROGBITS)
                    fprintf(rf, "progbits  ");
                else
                    fprintf(rf, "nobits    ");
                fprintf(rf, "%s\n", s->name);
            }
            fprintf(rf, "\n");
        }
        /* Display detailed section information. */
        if (map_control & MAP_SECTIONS) {
            fprintf(rf, "-- Sections (detailed) ");
            for (h = 56; h; h--)
                fputc('-', rf);
            fprintf(rf, "\n\n");
            for (s = sections; s; s = s->next) {
                fprintf(rf, "---- Section %s ", s->name);
                for (h = 65 - strlen(s->name); h; h--)
                    fputc('-', rf);
                fprintf(rf, "\n\nclass:     ");
                if (s->flags & TYPE_PROGBITS)
                    fprintf(rf, "progbits");
                else
                    fprintf(rf, "nobits");
                fprintf(rf, "\nlength:    %08lX\nstart:     %08lX"
                        "\nalign:     ", s->length, s->start);
                if (s->flags & ALIGN_DEFINED)
                    fprintf(rf, "%08lX", s->align);
                else
                    fprintf(rf, not_defined);
                fprintf(rf, "\nfollows:   ");
                if (s->flags & FOLLOWS_DEFINED)
                    fprintf(rf, "%s", s->follows);
                else
                    fprintf(rf, not_defined);
                fprintf(rf, "\nvstart:    %08lX\nvalign:    ", s->vstart);
                if (s->flags & VALIGN_DEFINED)
                    fprintf(rf, "%08lX", s->valign);
                else
                    fprintf(rf, not_defined);
                fprintf(rf, "\nvfollows:  ");
                if (s->flags & VFOLLOWS_DEFINED)
                    fprintf(rf, "%s", s->vfollows);
                else
                    fprintf(rf, not_defined);
                fprintf(rf, "\n\n");
            }
        }
        /* Display symbols information. */
        if (map_control & MAP_SYMBOLS) {
            long segment, offset;

            fprintf(rf, "-- Symbols ");
            for (h = 68; h; h--)
                fputc('-', rf);
            fprintf(rf, "\n\n");
            if (no_seg_labels) {
                fprintf(rf, "---- No Section ");
                for (h = 63; h; h--)
                    fputc('-', rf);
                fprintf(rf, "\n\nValue     Name\n");
                for (l = no_seg_labels; l; l = l->next) {
                    lookup_label(l->name, &segment, &offset);
                    fprintf(rf, "%08lX  %s\n", offset, l->name);
                }
                fprintf(rf, "\n\n");
            }
            for (s = sections; s; s = s->next) {
                if (s->labels) {
                    fprintf(rf, "---- Section %s ", s->name);
                    for (h = 65 - strlen(s->name); h; h--)
                        fputc('-', rf);
                    fprintf(rf, "\n\nReal      Virtual   Name\n");
                    for (l = s->labels; l; l = l->next) {
                        lookup_label(l->name, &segment, &offset);
                        fprintf(rf, "%08lX  %08lX  %s\n",
                                s->start + offset, s->vstart + offset,
                                l->name);
                    }
                    fprintf(rf, "\n");
                }
            }
        }
    }

    /* Close the report file. */
    if (map_control && (rf != stdout) && (rf != stderr))
        fclose(rf);

    /* Step 8: Release all allocated memory. */

    /* Free sections, label pointer structs, etc.. */
    while (sections) {
        s = sections;
        sections = s->next;
        saa_free(s->contents);
        nasm_free(s->name);
        if (s->flags & FOLLOWS_DEFINED)
            nasm_free(s->follows);
        if (s->flags & VFOLLOWS_DEFINED)
            nasm_free(s->vfollows);
        while (s->labels) {
            l = s->labels;
            s->labels = l->next;
            nasm_free(l);
        }
        nasm_free(s);
    }

    /* Free no-section labels. */
    while (no_seg_labels) {
        l = no_seg_labels;
        no_seg_labels = l->next;

⌨️ 快捷键说明

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