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

📄 outbin.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 C
📖 第 1 页 / 共 4 页
字号:
static void bin_out (long segto, const void *data, unsigned long type,           long segment, long wrt){  unsigned char *p, mydata[4];   struct Section *s;   long realbytes;   if (wrt != NO_SEG)   {  wrt = NO_SEG;        /* continue to do _something_ */      error (ERR_NONFATAL,         "WRT not supported by binary output format");   }   /* Handle absolute-assembly (structure definitions). */   if (segto == NO_SEG)   {  if ((type & OUT_TYPMASK) != OUT_RESERVE)         error (ERR_NONFATAL, "attempt to assemble code in"            " [ABSOLUTE] space");      return;   }   /* Find the segment we are targeting. */   s = find_section_by_index(segto);   if (!s)      error (ERR_PANIC, "code directed to nonexistent segment?");   /* "Smart" section-type adaptation code. */   if (!(s->flags & TYPE_DEFINED))   {  if ((type & OUT_TYPMASK) == OUT_RESERVE)         s->flags |= TYPE_DEFINED | TYPE_NOBITS;      else s->flags |= TYPE_DEFINED | TYPE_PROGBITS;   }   if ((s->flags & TYPE_NOBITS) && ((type & OUT_TYPMASK) != OUT_RESERVE))      error(ERR_WARNING, "attempt to initialise memory in a"         " nobits section: ignored");   if ((type & OUT_TYPMASK) == OUT_ADDRESS)   {  if (segment != NO_SEG && !find_section_by_index(segment))      {  if (segment % 2)            error(ERR_NONFATAL, "binary output format does not support"               " segment base references");         else            error(ERR_NONFATAL, "binary output format does not support"               " external references");         segment = NO_SEG;      }      if (s->flags & TYPE_PROGBITS)      {  if (segment != NO_SEG)            add_reloc(s, type & OUT_SIZMASK, segment, -1L);         p = mydata;         if ((type & OUT_SIZMASK) == 4)            WRITELONG(p, *(long *)data);         else            WRITESHORT(p, *(long *)data);         saa_wbytes(s->contents, mydata, type & OUT_SIZMASK);      }      s->length += type & OUT_SIZMASK;   }   else if ((type & OUT_TYPMASK) == OUT_RAWDATA)   {  type &= OUT_SIZMASK;      if (s->flags & TYPE_PROGBITS) saa_wbytes(s->contents, data, type);      s->length += type;   }   else if ((type & OUT_TYPMASK) == OUT_RESERVE)   {  type &= OUT_SIZMASK;      if (s->flags & TYPE_PROGBITS)      {  error(ERR_WARNING, "uninitialised space declared in"            " %s section: zeroing", s->name);         saa_wbytes (s->contents, NULL, type);      }      s->length += type;   }   else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||      (type & OUT_TYPMASK) == OUT_REL4ADR)   {  realbytes = ((type & OUT_TYPMASK) == OUT_REL4ADR ? 4 : 2);      if (segment != NO_SEG && !find_section_by_index(segment))      {  if (segment % 2)            error(ERR_NONFATAL, "binary output format does not support"               " segment base references");         else            error(ERR_NONFATAL, "binary output format does not support"               " external references");         segment = NO_SEG;      }      if (s->flags & TYPE_PROGBITS)      {  add_reloc(s, realbytes, segment, segto);         p = mydata;         if (realbytes == 4)            WRITELONG(p, *(long*)data - realbytes - s->length);         else            WRITESHORT(p, *(long*)data - realbytes - s->length);         saa_wbytes(s->contents, mydata, realbytes);      }      s->length += realbytes;   }}static void bin_deflabel (char *name, long segment, long offset,           int is_global, char *special){  (void) segment;   /* Don't warn that this parameter is unused */   (void) offset;    /* Don't warn that this parameter is unused */   if (special)      error (ERR_NONFATAL, "binary format does not support any"         " special symbol types");   else if (name[0] == '.' && name[1] == '.' && name[2] != '@')      error (ERR_NONFATAL, "unrecognised special symbol `%s'", name);   else if (is_global == 2)      error (ERR_NONFATAL, "binary output format does not support common"         " variables");   else   {  struct Section *s;      struct bin_label ***ltp;      /* Remember label definition so we can look it up later when       * creating the map file. */      s = find_section_by_index(segment);      if (s) ltp = &(s->labels_end);      else ltp = &nsl_tail;      (**ltp) = nasm_malloc(sizeof(struct bin_label));      (**ltp)->name = name;      (**ltp)->next = NULL;      *ltp = &((**ltp)->next);   }}/* These constants and the following function are used * by bin_secname() to parse attribute assignments. */enum { ATTRIB_START, ATTRIB_ALIGN, ATTRIB_FOLLOWS,       ATTRIB_VSTART, ATTRIB_VALIGN, ATTRIB_VFOLLOWS,       ATTRIB_NOBITS, ATTRIB_PROGBITS };static int bin_read_attribute(char **line, int *attribute, unsigned long *value){  expr *e;   int attrib_name_size;   struct tokenval tokval;   char *exp;   /* Skip whitespace. */   while (**line && isspace(**line)) (*line)++;   if (!**line) return 0;   /* Figure out what attribute we're reading. */   if (!nasm_strnicmp(*line,"align=", 6))   {  *attribute = ATTRIB_ALIGN;      attrib_name_size = 6;   }   else if (format_mode)   {  if (!nasm_strnicmp(*line,"start=", 6))      {  *attribute = ATTRIB_START;         attrib_name_size = 6;      }      else if (!nasm_strnicmp(*line,"follows=", 8))      {  *attribute = ATTRIB_FOLLOWS;         *line += 8; return 1;      }      else if (!nasm_strnicmp(*line,"vstart=", 7))      {  *attribute = ATTRIB_VSTART;         attrib_name_size = 7;      }      else if (!nasm_strnicmp(*line,"valign=", 7))      {  *attribute = ATTRIB_VALIGN;         attrib_name_size = 7;      }      else if (!nasm_strnicmp(*line,"vfollows=", 9))      {  *attribute = ATTRIB_VFOLLOWS;         *line += 9; return 1;      }      else if (!nasm_strnicmp(*line,"nobits", 6) &&         (isspace((*line)[6]) || ((*line)[6] == '\0')))      {  *attribute = ATTRIB_NOBITS;         *line += 6; return 1;      }      else if (!nasm_strnicmp(*line,"progbits", 8) &&         (isspace((*line)[8]) || ((*line)[8] == '\0')))      {  *attribute = ATTRIB_PROGBITS;         *line += 8; return 1;      }      else return 0;   }   else return 0;   /* Find the end of the expression. */   if ((*line)[attrib_name_size] != '(')   {      /* Single term (no parenthesis). */      exp = *line += attrib_name_size;      while (**line && !isspace(**line)) (*line)++;      if (**line)      {  **line = '\0'; (*line)++;      }   }   else   {  char c;      int pcount = 1;      /* Full expression (delimited by parenthesis) */      exp = *line += attrib_name_size + 1;      while (1)      {  (*line) += strcspn(*line, "()'\"");         if (**line == '(')         {  ++(*line); ++pcount;         }         if (**line == ')')         {  ++(*line); --pcount;            if (!pcount) break;         }         if ((**line == '"') || (**line == '\''))         {  c = **line;            while (**line)            {  ++(*line);               if (**line == c) break;            }            if (!**line)            {  error(ERR_NONFATAL, "invalid syntax in `section' directive");               return -1;            }            ++(*line);         }         if (!**line)         {  error(ERR_NONFATAL, "expecting `)'");            return -1;         }      }      *(*line - 1) = '\0';  /* Terminate the expression. */   }   /* Check for no value given. */   if (!*exp)   {  error(ERR_WARNING, "No value given to attribute in"         " `section' directive");      return -1;   }   /* Read and evaluate the expression. */   stdscan_reset();   stdscan_bufptr = exp;   tokval.t_type = TOKEN_INVALID;   e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);   if (e)   {  if (!is_really_simple(e))      {  error(ERR_NONFATAL, "section attribute value must be"            " a critical expression");         return -1;      }   }   else   {  error(ERR_NONFATAL, "Invalid attribute value"         " specified in `section' directive.");      return -1;   }   *value = (unsigned long) reloc_value(e);   return 1;}static void bin_assign_attributes(struct Section *sec, char *astring){  int attribute, check;   unsigned long value;   char *p;   while (1)   {  /* Get the next attribute. */      check = bin_read_attribute(&astring, &attribute, &value);      /* Skip bad attribute. */      if (check == -1) continue;      /* Unknown section attribute, so skip it and warn the user. */      if (!check)      {  if (!*astring) break;  /* End of line. */         else         {  p = astring; while (*astring && !isspace(*astring)) astring++;            if (*astring)            {  *astring = '\0'; astring++;            }            error(ERR_WARNING, "ignoring unknown section attribute:"               " \"%s\"", p);         }      continue;      }      switch (attribute)      {  /* Handle nobits attribute. */         case ATTRIB_NOBITS:            if ((sec->flags & TYPE_DEFINED) && (sec->flags & TYPE_PROGBITS))               error(ERR_NONFATAL, "attempt to change section type"                  " from progbits to nobits");            else sec->flags |= TYPE_DEFINED | TYPE_NOBITS;            continue;         /* Handle progbits attribute. */         case ATTRIB_PROGBITS:            if ((sec->flags & TYPE_DEFINED) && (sec->flags & TYPE_NOBITS))               error(ERR_NONFATAL, "attempt to change section type"                  " from nobits to progbits");            else sec->flags |= TYPE_DEFINED | TYPE_PROGBITS;            continue;         /* Handle align attribute. */         case ATTRIB_ALIGN:            if (!format_mode && (!strcmp(sec->name, ".text")))               error(ERR_NONFATAL, "cannot specify an alignment"                  " to the .text section");            else            {  if (!value || ((value - 1) & value))                  error(ERR_NONFATAL, "argument to `align' is not a"                  " power of two");               else               {  /* Alignment is already satisfied if the previous                   * align value is greater. */                  if ((sec->flags & ALIGN_DEFINED) && (value < sec->align))                     value = sec->align;                  /* Don't allow a conflicting align value. */                  if ((sec->flags & START_DEFINED) && (sec->start & (value - 1)))                     error(ERR_NONFATAL, "`align' value conflicts "                     "with section start address");                  else                  {  sec->align = value; sec->flags |= ALIGN_DEFINED;                  }               }            }            continue;         /* Handle valign attribute. */         case ATTRIB_VALIGN:            if (!value || ((value - 1) & value))               error(ERR_NONFATAL, "argument to `valign' is not a"                  " power of two");            else

⌨️ 快捷键说明

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