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