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

📄 xdf-objfmt.c

📁 支持AMD64的汇编编译器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    /*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d;    yasm_objfmt_xdf *objfmt_xdf;    /*@dependent@*/ /*@null@*/ xdf_section_data *xsd;    /*@null@*/ xdf_symrec_data *xsymd;    unsigned char *localbuf;    /* Don't output absolute sections into the section table */    if (yasm_section_is_absolute(sect))	return 0;    assert(info != NULL);    objfmt_xdf = info->objfmt_xdf;    xsd = yasm_section_get_data(sect, &xdf_section_data_cb);    assert(xsd != NULL);    localbuf = info->buf;    xsymd = yasm_symrec_get_data(xsd->sym, &xdf_symrec_data_cb);    assert(xsymd != NULL);    YASM_WRITE_32_L(localbuf, xsymd->index);	/* section name symbol */    if (xsd->addr) {	yasm_intnum_get_sized(xsd->addr, localbuf, 8, 64, 0, 0, 0, 0);	localbuf += 8;				/* physical address */    } else {	YASM_WRITE_32_L(localbuf, 0);	YASM_WRITE_32_L(localbuf, 0);    }    YASM_WRITE_16_L(localbuf, xsd->align);	/* alignment */    YASM_WRITE_16_L(localbuf, xsd->flags);	/* flags */    YASM_WRITE_32_L(localbuf, xsd->scnptr);	/* file ptr to data */    YASM_WRITE_32_L(localbuf, xsd->size);	/* section size */    YASM_WRITE_32_L(localbuf, xsd->relptr);	/* file ptr to relocs */    YASM_WRITE_32_L(localbuf, xsd->nreloc); /* num of relocation entries */    fwrite(info->buf, 32, 1, info->f);    return 0;}static voidxdf_objfmt_output(yasm_objfmt *objfmt, FILE *f, const char *obj_filename,		   int all_syms, /*@unused@*/ yasm_dbgfmt *df){    yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt;    xdf_objfmt_output_info info;    unsigned char *localbuf;    unsigned long symtab_count = 0;    unsigned long strtab_offset;    xdf_symtab_entry *entry;    info.objfmt_xdf = objfmt_xdf;    info.f = f;    info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE);    /* Allocate space for headers by seeking forward */    if (fseek(f, (long)(16+32*(objfmt_xdf->parse_scnum)), SEEK_SET) < 0) {	yasm__fatal(N_("could not seek on output file"));	/*@notreached@*/	return;    }    /* Symbol table */    all_syms = 1;	/* force all syms into symbol table */    if (all_syms) {	/* Need to put all local syms into XDF symbol table */	yasm_symtab_traverse(objfmt_xdf->symtab, objfmt_xdf,			     xdf_objfmt_append_local_sym);    }    /* Get number of symbols */    if (STAILQ_EMPTY(&objfmt_xdf->xdf_symtab))	symtab_count = 0;    else {	/*@null@*/ /*@dependent@*/ xdf_symrec_data *sym_data_prev;	entry = STAILQ_LAST(&objfmt_xdf->xdf_symtab, xdf_symtab_entry, link);	sym_data_prev = yasm_symrec_get_data(entry->sym, &xdf_symrec_data_cb);	assert(sym_data_prev != NULL);	symtab_count = sym_data_prev->index + 1;    }    /* Get file offset of start of string table */    strtab_offset = 16+32*(objfmt_xdf->parse_scnum)+16*symtab_count;    STAILQ_FOREACH(entry, &objfmt_xdf->xdf_symtab, link) {	const char *name = yasm_symrec_get_name(entry->sym);	const yasm_expr *equ_val;	const yasm_intnum *intn;	size_t len = strlen(name);	/*@dependent@*/ /*@null@*/ xdf_symrec_data *xsymd;	unsigned long value = 0;	long scnum = -3;	/* -3 = debugging symbol */	/*@dependent@*/ /*@null@*/ yasm_section *sect;	/*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;	yasm_sym_vis vis = yasm_symrec_get_visibility(entry->sym);	unsigned long flags = 0;	/* Get symrec's of_data (needed for storage class) */	xsymd = yasm_symrec_get_data(entry->sym, &xdf_symrec_data_cb);	if (!xsymd)	    yasm_internal_error(N_("xdf: expected sym data to be present"));	if (vis & YASM_SYM_GLOBAL)	    flags = XDF_SYM_GLOBAL;	/* Look at symrec for value/scnum/etc. */	if (yasm_symrec_get_label(entry->sym, &precbc)) {	    if (precbc)		sect = yasm_bc_get_section(precbc);	    else		sect = NULL;	    /* it's a label: get value and offset.	     * If there is not a section, leave as debugging symbol.	     */	    if (sect) {		/*@dependent@*/ /*@null@*/ xdf_section_data *csectd;		csectd = yasm_section_get_data(sect, &xdf_section_data_cb);		if (csectd) {		    scnum = csectd->scnum;		} else if (yasm_section_is_absolute(sect)) {		    yasm_expr *abs_start;		    abs_start = yasm_expr_copy(yasm_section_get_start(sect));		    intn = yasm_expr_get_intnum(&abs_start,						yasm_common_calc_bc_dist);		    if (!intn)			yasm__error(abs_start->line,			    N_("absolute section start not an integer expression"));		    else			value = yasm_intnum_get_uint(intn);		    yasm_expr_destroy(abs_start);		    flags |= XDF_SYM_EQU;		    scnum = -2;	/* -2 = absolute symbol */		} else		    yasm_internal_error(N_("didn't understand section"));		if (precbc)		    value += precbc->offset + precbc->len;	    }	} else if ((equ_val = yasm_symrec_get_equ(entry->sym))) {	    yasm_expr *equ_val_copy = yasm_expr_copy(equ_val);	    intn = yasm_expr_get_intnum(&equ_val_copy,					yasm_common_calc_bc_dist);	    if (!intn) {		if (vis & YASM_SYM_GLOBAL)		    yasm__error(equ_val->line,			N_("global EQU value not an integer expression"));	    } else		value = yasm_intnum_get_uint(intn);	    yasm_expr_destroy(equ_val_copy);	    flags |= XDF_SYM_EQU;	    scnum = -2;     /* -2 = absolute symbol */	} else {	    if (vis & YASM_SYM_EXTERN) {		flags = XDF_SYM_EXTERN;		scnum = -1;	    }	}	localbuf = info.buf;	YASM_WRITE_32_L(localbuf, scnum);	/* section number */	YASM_WRITE_32_L(localbuf, value);	/* value */	YASM_WRITE_32_L(localbuf, strtab_offset); /* string table offset */	strtab_offset += len+1;	YASM_WRITE_32_L(localbuf, flags);	/* flags */	fwrite(info.buf, 16, 1, f);    }    /* String table */    STAILQ_FOREACH(entry, &objfmt_xdf->xdf_symtab, link) {	const char *name = yasm_symrec_get_name(entry->sym);	size_t len = strlen(name);	fwrite(name, len+1, 1, f);    }    /* Section data/relocs */    if (yasm_object_sections_traverse(objfmt_xdf->object, &info,				      xdf_objfmt_output_section))	return;    /* 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_32_L(localbuf, XDF_MAGIC);	/* magic number */    YASM_WRITE_32_L(localbuf, objfmt_xdf->parse_scnum); /* number of sects */    YASM_WRITE_32_L(localbuf, symtab_count);		/* number of symtabs */    /* size of sect headers + symbol table + strings */    YASM_WRITE_32_L(localbuf, strtab_offset-16);    fwrite(info.buf, 16, 1, f);    yasm_object_sections_traverse(objfmt_xdf->object, &info,				  xdf_objfmt_output_secthead);    yasm_xfree(info.buf);}static voidxdf_objfmt_destroy(yasm_objfmt *objfmt){    yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt;    xdf_symtab_entry *entry1, *entry2;    /* Delete local symbol table */    entry1 = STAILQ_FIRST(&objfmt_xdf->xdf_symtab);    while (entry1 != NULL) {	entry2 = STAILQ_NEXT(entry1, link);	yasm_xfree(entry1);	entry1 = entry2;    }    yasm_xfree(objfmt);}static /*@observer@*/ /*@null@*/ yasm_section *xdf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,			    /*@unused@*/ /*@null@*/			    yasm_valparamhead *objext_valparams,			    unsigned long line){    yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt;    yasm_valparam *vp = yasm_vps_first(valparams);    yasm_section *retval;    int isnew;    /*@dependent@*/ /*@null@*/ const yasm_intnum *absaddr = NULL;    unsigned int addralign = 0;    unsigned long flags = 0;    int flags_override = 0;    char *sectname;    int resonly = 0;    if (!vp || vp->param || !vp->val)	return NULL;    sectname = vp->val;    while ((vp = yasm_vps_next(vp))) {	flags_override = 1;	if (yasm__strcasecmp(vp->val, "use16") == 0) {	    flags &= ~(XDF_SECT_USE_32|XDF_SECT_USE_64);	    flags |= XDF_SECT_USE_16;	    yasm_arch_set_var(objfmt_xdf->arch, "mode_bits", 16);	} else if (yasm__strcasecmp(vp->val, "use32") == 0) {	    flags &= ~(XDF_SECT_USE_16|XDF_SECT_USE_64);	    flags |= XDF_SECT_USE_32;	    yasm_arch_set_var(objfmt_xdf->arch, "mode_bits", 32);	} else if (yasm__strcasecmp(vp->val, "use64") == 0) {	    flags &= ~(XDF_SECT_USE_16|XDF_SECT_USE_32);	    flags |= XDF_SECT_USE_64;	    yasm_arch_set_var(objfmt_xdf->arch, "mode_bits", 64);	} else if (yasm__strcasecmp(vp->val, "bss") == 0) {	    flags |= XDF_SECT_BSS;	} else if (yasm__strcasecmp(vp->val, "flat") == 0) {	    flags |= XDF_SECT_FLAT;	} else if (yasm__strcasecmp(vp->val, "absolute") == 0 && vp->param) {	    flags |= XDF_SECT_ABSOLUTE;	    absaddr = yasm_expr_get_intnum(&vp->param, NULL);	    if (!absaddr) {		yasm__error(line, N_("argument to `%s' is not an integer"),			    vp->val);		return NULL;	    }	} else if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) {	    /*@dependent@*/ /*@null@*/ const yasm_intnum *align;	    unsigned long bitcnt;	    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 > 4096) {		yasm__error(line,			    N_("XDF does not support alignments > 4096"));		return NULL;	    }	} else	    yasm__warning(YASM_WARN_GENERAL, line,			  N_("Unrecognized qualifier `%s'"), vp->val);    }    retval = yasm_object_get_general(objfmt_xdf->object, sectname, 0, resonly,				     &isnew, line);    if (isnew) {	xdf_section_data *data;	yasm_symrec *sym;	data = yasm_xmalloc(sizeof(xdf_section_data));	data->scnum = objfmt_xdf->parse_scnum++;	data->align = addralign;	data->flags = flags;	if (absaddr)	    data->addr = yasm_intnum_copy(absaddr);	else	    data->addr = NULL;	data->scnptr = 0;	data->size = 0;	data->relptr = 0;	data->nreloc = 0;	STAILQ_INIT(&data->relocs);	yasm_section_add_data(retval, &xdf_section_data_cb, data);	sym =	    yasm_symtab_define_label(objfmt_xdf->symtab, sectname,				     yasm_section_bcs_first(retval), 1, line);	xdf_objfmt_symtab_append(objfmt_xdf, sym);	data->sym = sym;    } else if (flags_override)	yasm__warning(YASM_WARN_GENERAL, line,		      N_("section flags ignored on section redeclaration"));    return retval;}static voidxdf_section_data_destroy(void *data){    xdf_section_data *xsd = (xdf_section_data *)data;    if (xsd->addr)	yasm_intnum_destroy(xsd->addr);    yasm_xfree(data);}static voidxdf_section_data_print(void *data, FILE *f, int indent_level){    xdf_section_data *xsd = (xdf_section_data *)data;    fprintf(f, "%*ssym=\n", indent_level, "");    yasm_symrec_print(xsd->sym, f, indent_level+1);    fprintf(f, "%*sscnum=%ld\n", indent_level, "", xsd->scnum);    fprintf(f, "%*sflags=0x%x\n", indent_level, "", xsd->flags);    fprintf(f, "%*saddr=", indent_level, "");    yasm_intnum_print(xsd->addr, f);    fprintf(f, "%*sscnptr=0x%lx\n", indent_level, "", xsd->scnptr);    fprintf(f, "%*ssize=%ld\n", indent_level, "", xsd->size);    fprintf(f, "%*srelptr=0x%lx\n", indent_level, "", xsd->relptr);    fprintf(f, "%*snreloc=%ld\n", indent_level, "", xsd->nreloc);    fprintf(f, "%*srelocs:\n", indent_level, "");}static yasm_symrec *xdf_objfmt_extern_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/			   /*@null@*/ yasm_valparamhead *objext_valparams,			   unsigned long line){    yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt;    yasm_symrec *sym;    sym = yasm_symtab_declare(objfmt_xdf->symtab, name, YASM_SYM_EXTERN,			      line);    xdf_objfmt_symtab_append(objfmt_xdf, sym);    return sym;}static yasm_symrec *xdf_objfmt_global_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/			   /*@null@*/ yasm_valparamhead *objext_valparams,			   unsigned long line){    yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt;    yasm_symrec *sym;    sym = yasm_symtab_declare(objfmt_xdf->symtab, name, YASM_SYM_GLOBAL,			      line);    xdf_objfmt_symtab_append(objfmt_xdf, sym);    return sym;}static yasm_symrec *xdf_objfmt_common_declare(yasm_objfmt *objfmt, const char *name,			   /*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/			   yasm_valparamhead *objext_valparams,			   unsigned long line){    yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt;    yasm_symrec *sym;    yasm_expr_destroy(size);    yasm__error(line,	N_("XDF object format does not support common variables"));    sym = yasm_symtab_declare(objfmt_xdf->symtab, name, YASM_SYM_COMMON, line);    return sym;}static voidxdf_symrec_data_destroy(void *data){    yasm_xfree(data);}static voidxdf_symrec_data_print(void *data, FILE *f, int indent_level){    xdf_symrec_data *xsd = (xdf_symrec_data *)data;    fprintf(f, "%*ssymtab index=%lu\n", indent_level, "", xsd->index);}static intxdf_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 *xdf_objfmt_dbgfmt_keywords[] = {    "null",    NULL};/* Define objfmt structure -- see objfmt.h for details */yasm_objfmt_module yasm_xdf_LTX_objfmt = {    YASM_OBJFMT_VERSION,    "Extended Dynamic Object",    "xdf",    "xdf",    ".text",    32,    xdf_objfmt_dbgfmt_keywords,    "null",    xdf_objfmt_create,    xdf_objfmt_output,    xdf_objfmt_destroy,    xdf_objfmt_section_switch,    xdf_objfmt_extern_declare,    xdf_objfmt_global_declare,    xdf_objfmt_common_declare,    xdf_objfmt_directive};

⌨️ 快捷键说明

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