📄 outbin.c
字号:
* will always be the first section in the unsorted list). */ for (g = sections, sections = NULL; g; g = gs) { /* Find the section that we will insert this group before (s). */ for (sp = §ions, s = sections; s; sp = &s->next, s = s->next) if ((s->flags & START_DEFINED) && (g->start < s->start)) break; /* Find the end of the group (gs). */ for (gs = g->next, gsp = &g->next; 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; nasm_free(l); } /* Free relocation structures. */ while (relocs) { r = relocs->next; nasm_free(relocs); relocs = r; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -