📄 outbin.c
字号:
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 + -