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

📄 outbin.c

📁 一个免费的汇编语言编译器的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            {  /* Alignment is already satisfied if the previous
                * align value is greater. */
               if ((sec->flags & VALIGN_DEFINED) && (value < sec->valign))
                  value = sec->valign;

               /* Don't allow a conflicting valign value. */
               if ((sec->flags & VSTART_DEFINED) && (sec->vstart & (value - 1)))
                  error(ERR_NONFATAL, "`valign' value conflicts "
                     "with `vstart' address");
               else
               {  sec->valign = value; sec->flags |= VALIGN_DEFINED;
               }
            }
            continue;

         /* Handle start attribute. */
         case ATTRIB_START:
            if (sec->flags & FOLLOWS_DEFINED)
               error(ERR_NONFATAL, "cannot combine `start' and `follows'"
                  " section attributes");
            else if (value < 0)
               error(ERR_NONFATAL, "attempt to specify a negative"
                  " section start address");
            else if ((sec->flags & START_DEFINED) && (value != sec->start))
               error(ERR_NONFATAL, "section start address redefined");
            else
            {  sec->start = value; sec->flags |= START_DEFINED;
               if (sec->flags & ALIGN_DEFINED)
               {  if (sec->start & (sec->align - 1))
                     error (ERR_NONFATAL, "`start' address conflicts"
                        " with section alignment");
                  sec->flags ^= ALIGN_DEFINED;
               }
            }
            continue;

         /* Handle vstart attribute. */
         case ATTRIB_VSTART:
            if (sec->flags & VFOLLOWS_DEFINED)
               error(ERR_NONFATAL, "cannot combine `vstart' and `vfollows'"
                  " section attributes");
            else if ((sec->flags & VSTART_DEFINED) && (value != sec->vstart))
               error(ERR_NONFATAL, "section virtual start address"
                  " (vstart) redefined");
            else
            {  sec->vstart = value; sec->flags |= VSTART_DEFINED;
               if (sec->flags & VALIGN_DEFINED)
               {  if (sec->vstart & (sec->valign - 1))
                     error (ERR_NONFATAL, "`vstart' address conflicts"
                        " with `valign' value");
                  sec->flags ^= VALIGN_DEFINED;
               }
            }
            continue;

         /* Handle follows attribute. */
         case ATTRIB_FOLLOWS:
            p = astring; astring += strcspn(astring, " \t");
            if (astring == p)
               error(ERR_NONFATAL, "expecting section name for `follows'"
                  " attribute");
            else
            {  *(astring++) = '\0';
               if (sec->flags & START_DEFINED)
                  error(ERR_NONFATAL, "cannot combine `start' and `follows'"
                     " section attributes");
               sec->follows = nasm_strdup(p);
               sec->flags |= FOLLOWS_DEFINED;
            }
            continue;

         /* Handle vfollows attribute. */
         case ATTRIB_VFOLLOWS:
            if (sec->flags & VSTART_DEFINED)
               error(ERR_NONFATAL, "cannot combine `vstart' and `vfollows'"
                  " section attributes");
            else
            {  p = astring; astring += strcspn(astring, " \t");
               if (astring == p)
                  error(ERR_NONFATAL, "expecting section name for `vfollows'"
                     " attribute");
               else
               {  *(astring++) = '\0';
                  sec->vfollows = nasm_strdup(p);
                  sec->flags |= VFOLLOWS_DEFINED;
               }
            }
            continue;
      }
   }
}

static void bin_define_section_labels()
{  static int labels_defined = 0;
   struct Section * sec;
   char * label_name;
   size_t base_len;

   if (labels_defined) return;
   for (sec = sections; sec; sec = sec->next)
   {  base_len = strlen(sec->name) + 8;
      label_name = nasm_malloc(base_len + 8);
      strcpy(label_name, "section.");
      strcpy(label_name + 8, sec->name);

      /* section.<name>.start */
      strcpy(label_name + base_len, ".start");
      define_label(label_name, sec->start_index, 0L,
         NULL, 0, 0, bin_get_ofmt(), error);

      /* section.<name>.vstart */
      strcpy(label_name + base_len, ".vstart");
      define_label(label_name, sec->vstart_index, 0L,
         NULL, 0, 0, bin_get_ofmt(), error);

      nasm_free(label_name);
   }
   labels_defined = 1;
}

static long bin_secname(char *name, int pass, int *bits)
{  char *p;
   struct Section *sec;

   /* bin_secname is called with *name = NULL at the start of each
    * pass.  Use this opportunity to establish the default section
    * (default is BITS-16 ".text" segment).
    */
   if (!name)
   {  /* Reset ORG and section attributes at the start of each pass. */
      origin_defined = 0;
      for (sec = sections; sec; sec = sec->next)
         sec->flags &= ~(START_DEFINED | VSTART_DEFINED |
            ALIGN_DEFINED | VALIGN_DEFINED);

      /* Define section start and vstart labels. */
      if (format_mode && (pass != 1)) bin_define_section_labels();

      /* Establish the default (.text) section. */
      *bits = 16;
      sec = find_section_by_name(".text");
      sec->flags |= TYPE_DEFINED | TYPE_PROGBITS;
      current_section = sec->vstart_index;
      return current_section;
   }

   /* Attempt to find the requested section.  If it does not
    * exist, create it. */
   p = name;
   while (*p && !isspace(*p)) p++;
   if (*p) *p++ = '\0';
   sec = find_section_by_name(name);
   if(!sec)
   {  sec = create_section(name);
      if (!strcmp(name, ".data"))
         sec->flags |= TYPE_DEFINED | TYPE_PROGBITS;
      else if (!strcmp(name, ".bss"))
      {  sec->flags |= TYPE_DEFINED | TYPE_NOBITS;
         sec->ifollows = NULL;
      }
      else if (!format_mode)
      {  error(ERR_NONFATAL, "section name must be "
            ".text, .data, or .bss");
         return current_section;
      }
   }

   /* Handle attribute assignments. */
   if (pass != 1) bin_assign_attributes(sec, p);

#ifndef ABIN_SMART_ADAPT
   /* The following line disables smart adaptation of
    * PROGBITS/NOBITS section types (it forces sections to
    * default to PROGBITS). */
   if ((pass != 1) && !(sec->flags & TYPE_DEFINED))
      sec->flags |= TYPE_DEFINED | TYPE_PROGBITS;
#endif

   /* Set the current section and return. */
   current_section = sec->vstart_index;
   return current_section;
}

static int bin_directive (char *directive, char *args, int pass)
{
   /* Handle ORG directive */
   if (!nasm_stricmp(directive, "org"))
   {  struct tokenval tokval;
      unsigned long value;
      expr *e;

      stdscan_reset();
      stdscan_bufptr = args;
      tokval.t_type = TOKEN_INVALID;
      e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
      if (e)
      {  if (!is_really_simple(e))
            error(ERR_NONFATAL, "org value must be a critical"
               " expression");
         else
         {  value = reloc_value(e);
            /* Check for ORG redefinition. */
            if (origin_defined && (value != origin))
               error(ERR_NONFATAL, "program origin redefined");
            else
            {  origin = value;
               origin_defined = 1;
            }
         }
      }
      else
         error(ERR_NONFATAL, "No or invalid offset specified"
            " in ORG directive.");
      return 1;
   }

   /* The 'map' directive allows the user to generate section
    * and symbol information to stdout, stderr, or to a file. */
   else if (format_mode && !nasm_stricmp(directive, "map"))
   {  char *p;

      if (pass != 1) return 1;
      args += strspn(args, " \t");
      while (*args)
      {  p = args; args += strcspn(args, " \t");
         if (*args != '\0') *(args++) = '\0';
         if (!nasm_stricmp(p, "all"))
            map_control |= MAP_ORIGIN | MAP_SUMMARY | MAP_SECTIONS | MAP_SYMBOLS;
         else if (!nasm_stricmp(p, "brief"))
            map_control |= MAP_ORIGIN | MAP_SUMMARY;
         else if (!nasm_stricmp(p, "sections"))
            map_control |= MAP_ORIGIN | MAP_SUMMARY | MAP_SECTIONS;
         else if (!nasm_stricmp(p, "segments"))
            map_control |= MAP_ORIGIN | MAP_SUMMARY | MAP_SECTIONS;
         else if (!nasm_stricmp(p, "symbols"))
            map_control |= MAP_SYMBOLS;
         else if (!rf)
         {  if (!nasm_stricmp(p, "stdout"))
               rf = stdout;
            else if (!nasm_stricmp(p, "stderr"))
               rf = stderr;
            else
            {  /* Must be a filename. */
               rf = fopen(p, "wt");
               if (!rf)
               {  error(ERR_WARNING, "unable to open map file `%s'", p);
                  map_control = 0;
                  return 1;
	           }
            }
         }
         else error(ERR_WARNING, "map file already specified");
      }
      if (map_control == 0) map_control |= MAP_ORIGIN | MAP_SUMMARY;
      if (!rf) rf = stdout;
      return 1;
   }
   return 0;
}

static void bin_filename (char *inname, char *outname, efunc error)
{  standard_extension(inname, outname, "", error);
   infile = inname; outfile = outname;
}

static long bin_segbase (long segment)
{    return segment;
}

static int bin_set_info(enum geninfo type, char **val)
{  return 0;
}

static void bin_init (FILE *afp, efunc errfunc, ldfunc ldef, evalfunc eval)
{   fp = afp;
    error = errfunc;

    (void) eval;   /* Don't warn that this parameter is unused. */
    (void) ldef;   /* Placate optimizers. */

    relocs          = NULL;
    reloctail       = &relocs;
    origin_defined  = 0;
    no_seg_labels   = NULL;
    nsl_tail        = &no_seg_labels;
    format_mode     = 1; /* Extended bin format
                          * (set this to zero for old bin format). */

   /* Create default section (.text). */
   sections = last_section = nasm_malloc(sizeof(struct Section));
   last_section->next = NULL;
   last_section->name = nasm_strdup(".text");
   last_section->contents = saa_init(1L);
   last_section->follows = last_section->vfollows = 0;
   last_section->ifollows = NULL;
   last_section->length = 0;
   last_section->flags = TYPE_DEFINED | TYPE_PROGBITS;
   last_section->labels = NULL;
   last_section->labels_end = &(last_section->labels);
   last_section->start_index  = seg_alloc();
   last_section->vstart_index = current_section = seg_alloc();
}

struct ofmt of_bin = {
    "flat-form binary files (e.g. DOS .COM, .SYS)",
    "bin",
    NULL,
    null_debug_arr,
    &null_debug_form,
    bin_stdmac,
    bin_init,
    bin_set_info,
    bin_out,
    bin_deflabel,
    bin_secname,
    bin_segbase,
    bin_directive,
    bin_filename,
    bin_cleanup
};

/* This is needed for bin_define_section_labels() */
struct ofmt *bin_get_ofmt()
{  return &of_bin;
}

#endif   /* #ifdef OF_BIN */

⌨️ 快捷键说明

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