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

📄 coff-objfmt.c

📁 支持AMD64的汇编编译器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -