📄 coff-objfmt.c
字号:
for (aux=0; aux<entry->numaux; aux++) { switch (entry->auxtype) { case COFF_SYMTAB_AUX_FILE: len = strlen(entry->aux[0].fname); if (len > 14) fwrite(entry->aux[0].fname, len+1, 1, f); break; default: break; } } } /* Write headers */ if (fseek(f, 0, SEEK_SET) < 0) { yasm__fatal(N_("could not seek on output file")); /*@notreached@*/ return; } localbuf = info.buf; YASM_WRITE_16_L(localbuf, objfmt_coff->machine); /* magic number */ YASM_WRITE_16_L(localbuf, objfmt_coff->parse_scnum-1);/* number of sects */ YASM_WRITE_32_L(localbuf, 0); /* time/date stamp */ YASM_WRITE_32_L(localbuf, symtab_pos); /* file ptr to symtab */ YASM_WRITE_32_L(localbuf, symtab_count); /* number of symtabs */ YASM_WRITE_16_L(localbuf, 0); /* size of optional header (none) */ /* flags */ YASM_WRITE_16_L(localbuf, COFF_F_AR32WR|COFF_F_LNNO |(all_syms?0:COFF_F_LSYMS)); fwrite(info.buf, 20, 1, f); yasm_object_sections_traverse(objfmt_coff->object, &info, coff_objfmt_output_secthead); yasm_xfree(info.buf);}static voidcoff_objfmt_destroy(yasm_objfmt *objfmt){ yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; coff_symtab_entry *entry1, *entry2; /* Delete local symbol table */ entry1 = STAILQ_FIRST(&objfmt_coff->coff_symtab); while (entry1 != NULL) { entry2 = STAILQ_NEXT(entry1, link); if (entry1->numaux == 1 && entry1->auxtype == COFF_SYMTAB_AUX_FILE) yasm_xfree(entry1->aux[0].fname); yasm_xfree(entry1); entry1 = entry2; } yasm_xfree(objfmt);}static /*@observer@*/ /*@null@*/ yasm_section *coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; yasm_valparam *vp = yasm_vps_first(valparams); yasm_section *retval; int isnew; unsigned long flags; int flags_override = 0; char *sectname; int resonly = 0; static const struct { const char *name; unsigned long stdflags; /* if 0, win32 only qualifier */ unsigned long win32flags; /* Mode: 0 => clear specified bits * 1 => set specified bits * 2 => clear all bits, then set specified bits */ int mode; } flagquals[] = { { "code", COFF_STYP_TEXT, COFF_STYP_EXECUTE | COFF_STYP_READ, 2 }, { "text", COFF_STYP_TEXT, COFF_STYP_EXECUTE | COFF_STYP_READ, 2 }, { "data", COFF_STYP_DATA, COFF_STYP_READ | COFF_STYP_WRITE, 2 }, { "bss", COFF_STYP_BSS, COFF_STYP_READ | COFF_STYP_WRITE, 2 }, { "info", COFF_STYP_INFO, COFF_STYP_DISCARD | COFF_STYP_READ, 2 }, { "discard", 0, COFF_STYP_DISCARD, 1 }, { "nodiscard", 0, COFF_STYP_DISCARD, 0 }, { "cache", 0, COFF_STYP_NOCACHE, 0 }, { "nocache", 0, COFF_STYP_NOCACHE, 1 }, { "page", 0, COFF_STYP_NOPAGE, 0 }, { "nopage", 0, COFF_STYP_NOPAGE, 1 }, { "share", 0, COFF_STYP_SHARED, 1 }, { "noshare", 0, COFF_STYP_SHARED, 0 }, { "execute", 0, COFF_STYP_EXECUTE, 1 }, { "noexecute", 0, COFF_STYP_EXECUTE, 0 }, { "read", 0, COFF_STYP_READ, 1 }, { "noread", 0, COFF_STYP_READ, 0 }, { "write", 0, COFF_STYP_WRITE, 1 }, { "nowrite", 0, COFF_STYP_WRITE, 0 }, }; if (!vp || vp->param || !vp->val) return NULL; sectname = vp->val; if (strlen(sectname) > 8) { /* TODO: win32 format supports >8 character section names in object * files via "/nnnn" (where nnnn is decimal offset into string table). */ yasm__warning(YASM_WARN_GENERAL, line, N_("COFF section names limited to 8 characters: truncating")); sectname[8] = '\0'; } if (strcmp(sectname, ".data") == 0) { flags = COFF_STYP_DATA; if (objfmt_coff->win32) flags |= COFF_STYP_READ | COFF_STYP_WRITE | (3<<COFF_STYP_ALIGN_SHIFT); /* align=4 */ } else if (strcmp(sectname, ".bss") == 0) { flags = COFF_STYP_BSS; if (objfmt_coff->win32) flags |= COFF_STYP_READ | COFF_STYP_WRITE | (3<<COFF_STYP_ALIGN_SHIFT); /* align=4 */ resonly = 1; } else if (strcmp(sectname, ".text") == 0) { flags = COFF_STYP_TEXT; if (objfmt_coff->win32) flags |= COFF_STYP_EXECUTE | COFF_STYP_READ | (5<<COFF_STYP_ALIGN_SHIFT); /* align=16 */ } else if (strcmp(sectname, ".rdata") == 0) { flags = COFF_STYP_DATA; if (objfmt_coff->win32) flags |= COFF_STYP_READ | (4<<COFF_STYP_ALIGN_SHIFT); /* align=8 */ else yasm__warning(YASM_WARN_GENERAL, line, N_("Standard COFF does not support read-only data sections")); } else { /* Default to code */ flags = COFF_STYP_TEXT; if (objfmt_coff->win32) flags |= COFF_STYP_EXECUTE | COFF_STYP_READ; } while ((vp = yasm_vps_next(vp))) { size_t i; int match, win32warn; win32warn = 0; match = 0; for (i=0; i<NELEMS(flagquals) && !match; i++) { if (yasm__strcasecmp(vp->val, flagquals[i].name) == 0) { if (!objfmt_coff->win32 && flagquals[i].stdflags == 0) win32warn = 1; else switch (flagquals[i].mode) { case 0: flags &= ~flagquals[i].stdflags; if (objfmt_coff->win32) flags &= ~flagquals[i].win32flags; break; case 1: flags |= flagquals[i].stdflags; if (objfmt_coff->win32) flags |= flagquals[i].win32flags; break; case 2: flags &= ~COFF_STYP_STD_MASK; flags |= flagquals[i].stdflags; if (objfmt_coff->win32) { flags &= ~COFF_STYP_WIN32_MASK; flags |= flagquals[i].win32flags; } break; } flags_override = 1; match = 1; } } if (match) ; else if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) { if (objfmt_coff->win32) { /*@dependent@*/ /*@null@*/ const yasm_intnum *align; unsigned long bitcnt; unsigned long addralign; align = yasm_expr_get_intnum(&vp->param, NULL); if (!align) { yasm__error(line, N_("argument to `%s' is not a power of two"), vp->val); return NULL; } addralign = yasm_intnum_get_uint(align); /* Check to see if alignment is a power of two. * This can be checked by seeing if only one bit is set. */ BitCount(bitcnt, addralign); if (bitcnt > 1) { yasm__error(line, N_("argument to `%s' is not a power of two"), vp->val); return NULL; } /* Check to see if alignment is supported size */ if (addralign > 8192) { yasm__error(line, N_("Win32 does not support alignments > 8192")); return NULL; } /* Convert alignment into flags setting */ flags &= ~COFF_STYP_ALIGN_MASK; while (addralign != 0) { flags += 1<<COFF_STYP_ALIGN_SHIFT; addralign >>= 1; } } else win32warn = 1; } else yasm__warning(YASM_WARN_GENERAL, line, N_("Unrecognized qualifier `%s'"), vp->val); if (win32warn) yasm__warning(YASM_WARN_GENERAL, line, N_("Standard COFF does not support qualifier `%s'"), vp->val); } retval = yasm_object_get_general(objfmt_coff->object, sectname, 0, resonly, &isnew, line); if (isnew) { coff_section_data *data; yasm_symrec *sym; data = yasm_xmalloc(sizeof(coff_section_data)); data->scnum = objfmt_coff->parse_scnum++; data->flags = flags; data->addr = 0; data->scnptr = 0; data->size = 0; data->relptr = 0; data->nreloc = 0; yasm_section_add_data(retval, &coff_section_data_cb, data); sym = yasm_symtab_define_label(objfmt_coff->symtab, sectname, yasm_section_bcs_first(retval), 1, line); coff_objfmt_symtab_append(objfmt_coff, sym, COFF_SCL_STAT, NULL, 1, COFF_SYMTAB_AUX_SECT); data->sym = sym; } else if (flags_override) yasm__warning(YASM_WARN_GENERAL, line, N_("section flags ignored on section redeclaration")); return retval;}static voidcoff_section_data_destroy(void *data){ yasm_xfree(data);}static voidcoff_section_data_print(void *data, FILE *f, int indent_level){ coff_section_data *csd = (coff_section_data *)data; fprintf(f, "%*ssym=\n", indent_level, ""); yasm_symrec_print(csd->sym, f, indent_level+1); fprintf(f, "%*sscnum=%d\n", indent_level, "", csd->scnum); fprintf(f, "%*sflags=", indent_level, ""); switch (csd->flags & COFF_STYP_STD_MASK) { case COFF_STYP_TEXT: fprintf(f, "TEXT"); break; case COFF_STYP_DATA: fprintf(f, "DATA"); break; case COFF_STYP_BSS: fprintf(f, "BSS"); break; default: fprintf(f, "UNKNOWN"); break; } fprintf(f, "\n%*saddr=0x%lx\n", indent_level, "", csd->addr); fprintf(f, "%*sscnptr=0x%lx\n", indent_level, "", csd->scnptr); fprintf(f, "%*ssize=%ld\n", indent_level, "", csd->size); fprintf(f, "%*srelptr=0x%lx\n", indent_level, "", csd->relptr); fprintf(f, "%*snreloc=%ld\n", indent_level, "", csd->nreloc); fprintf(f, "%*srelocs:\n", indent_level, "");}static yasm_symrec *coff_objfmt_extern_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; yasm_symrec *sym; sym = yasm_symtab_declare(objfmt_coff->symtab, name, YASM_SYM_EXTERN, line); coff_objfmt_symtab_append(objfmt_coff, sym, COFF_SCL_EXT, NULL, 0, COFF_SYMTAB_AUX_NONE); return sym;}static yasm_symrec *coff_objfmt_global_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; yasm_symrec *sym; sym = yasm_symtab_declare(objfmt_coff->symtab, name, YASM_SYM_GLOBAL, line); coff_objfmt_symtab_append(objfmt_coff, sym, COFF_SCL_EXT, NULL, 0, COFF_SYMTAB_AUX_NONE); return sym;}static yasm_symrec *coff_objfmt_common_declare(yasm_objfmt *objfmt, const char *name, /*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; yasm_symrec *sym; sym = yasm_symtab_declare(objfmt_coff->symtab, name, YASM_SYM_COMMON, line); coff_objfmt_symtab_append(objfmt_coff, sym, COFF_SCL_EXT, size, 0, COFF_SYMTAB_AUX_NONE); return sym;}static voidcoff_symrec_data_destroy(void *data){ coff_symrec_data *csymd = (coff_symrec_data *)data; if (csymd->size) yasm_expr_destroy(csymd->size); yasm_xfree(data);}static voidcoff_symrec_data_print(void *data, FILE *f, int indent_level){ coff_symrec_data *csd = (coff_symrec_data *)data; fprintf(f, "%*ssymtab index=%lu\n", indent_level, "", csd->index); fprintf(f, "%*ssclass=%d\n", indent_level, "", csd->sclass); fprintf(f, "%*ssize=", indent_level, ""); if (csd->size) yasm_expr_print(csd->size, f); else fprintf(f, "nil"); fprintf(f, "\n");}static intcoff_objfmt_directive(/*@unused@*/ yasm_objfmt *objfmt, /*@unused@*/ const char *name, /*@unused@*/ yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, /*@unused@*/ unsigned long line){ return 1; /* no objfmt directives */}/* Define valid debug formats to use with this object format */static const char *coff_objfmt_dbgfmt_keywords[] = { "null", NULL};/* Define objfmt structure -- see objfmt.h for details */yasm_objfmt_module yasm_coff_LTX_objfmt = { YASM_OBJFMT_VERSION, "COFF (DJGPP)", "coff", "o", ".text", 32, coff_objfmt_dbgfmt_keywords, "null", coff_objfmt_create, coff_objfmt_output, coff_objfmt_destroy, coff_objfmt_section_switch, coff_objfmt_extern_declare, coff_objfmt_global_declare, coff_objfmt_common_declare, coff_objfmt_directive};/* Define objfmt structure -- see objfmt.h for details */yasm_objfmt_module yasm_win32_LTX_objfmt = { YASM_OBJFMT_VERSION, "Win32", "win32", "obj", ".text", 32, coff_objfmt_dbgfmt_keywords, "null", win32_objfmt_create, coff_objfmt_output, coff_objfmt_destroy, coff_objfmt_section_switch, coff_objfmt_extern_declare, coff_objfmt_global_declare, coff_objfmt_common_declare, coff_objfmt_directive};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -