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

📄 outbin.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 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 + -