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

📄 outbin.c

📁 一个免费的汇编语言编译器的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    * 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 = &sections, 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 + -