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

📄 outbin.c

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