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

📄 elf-objfmt.c

📁 支持AMD64的汇编编译器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	    elf_secthead_add_size(shead, sectsize);	    yasm_intnum_destroy(sectsize);	}	elf_secthead_set_index(shead, ++info->sindex);	return 0;    }    /* skip empty sections */    if (yasm_section_bcs_last(sect) == yasm_section_bcs_first(sect)) {	return 0;    }    if ((pos = ftell(info->f)) == -1)	yasm__error(0, N_("couldn't read position on output stream"));    pos = elf_secthead_set_file_offset(shead, pos);    if (fseek(info->f, pos, SEEK_SET) < 0)	yasm__error(0, N_("couldn't seek on output stream"));    info->sect = sect;    info->shead = shead;    yasm_section_bcs_traverse(sect, info, elf_objfmt_output_bytecode);    /* Empty?  Go on to next section */    if (elf_secthead_is_empty(shead))	return 0;    elf_secthead_set_index(shead, ++info->sindex);    /* No relocations to output?  Go on to next section */    if (elf_secthead_write_relocs_to_file(info->f, sect, shead) == 0)	return 0;    elf_secthead_set_rel_index(shead, ++info->sindex);    /* name the relocation section .rel[a].foo */    sectname = yasm_section_get_name(sect);    relname = elf_secthead_name_reloc_section(sectname);    elf_secthead_set_rel_name(shead,        elf_strtab_append_str(info->objfmt_elf->shstrtab, relname));    yasm_xfree(relname);    return 0;}static intelf_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d){    /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d;    /*@dependent@*/ /*@null@*/ elf_secthead *shead;    /* Don't output absolute sections into the section table */    if (yasm_section_is_absolute(sect))	return 0;    if (info == NULL)	yasm_internal_error("null info struct");    shead = yasm_section_get_data(sect, &elf_section_data);    if (shead == NULL)	yasm_internal_error("no section header attached to section");    if(elf_secthead_write_to_file(info->f, shead, info->sindex+1))	info->sindex++;    /* output strtab headers here? */    /* relocation entries for .foo are stored in section .rel[a].foo */    if(elf_secthead_write_rel_to_file(info->f, 3, sect, shead,				      info->sindex+1))	info->sindex++;    return 0;}static voidelf_objfmt_output(yasm_objfmt *objfmt, FILE *f, const char *obj_filename,		  int all_syms, yasm_dbgfmt *df){    yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt;    elf_objfmt_output_info info;    append_local_sym_info localsym_info;    long pos;    unsigned long elf_shead_addr;    elf_secthead *esdn;    unsigned long elf_strtab_offset, elf_shstrtab_offset, elf_symtab_offset;    unsigned long elf_strtab_size, elf_shstrtab_size, elf_symtab_size;    elf_strtab_entry *elf_strtab_name, *elf_shstrtab_name, *elf_symtab_name;    unsigned long elf_symtab_nlocal;    info.objfmt_elf = objfmt_elf;    info.f = f;    /* Allocate space for Ehdr by seeking forward */    if (fseek(f, (long)(elf_proghead_get_size()), SEEK_SET) < 0) {	yasm__error(0, N_("could not seek on output file"));	return;    }    /* add all (local) syms to symtab because relocation needs a symtab index     * if all_syms, register them by name.  if not, use strtab entry 0 */    localsym_info.local_names = all_syms;    localsym_info.objfmt_elf = objfmt_elf;    yasm_symtab_traverse(yasm_object_get_symtab(objfmt_elf->object),			 &localsym_info, elf_objfmt_append_local_sym);    elf_symtab_nlocal = elf_symtab_assign_indices(objfmt_elf->elf_symtab);    /* output known sections - includes reloc sections which aren't in yasm's     * list.  Assign indices as we go. */    info.sindex = 3;    if (yasm_object_sections_traverse(objfmt_elf->object, &info,				      elf_objfmt_output_section))	return;    /* add final sections to the shstrtab */    elf_strtab_name = elf_strtab_append_str(objfmt_elf->shstrtab, ".strtab");    elf_symtab_name = elf_strtab_append_str(objfmt_elf->shstrtab, ".symtab");    elf_shstrtab_name = elf_strtab_append_str(objfmt_elf->shstrtab,					      ".shstrtab");    /* output .shstrtab */    if ((pos = elf_objfmt_output_align(f, 4)) == -1)	return;    elf_shstrtab_offset = (unsigned long) pos;    elf_shstrtab_size = elf_strtab_output_to_file(f, objfmt_elf->shstrtab);    /* output .strtab */    if ((pos = elf_objfmt_output_align(f, 4)) == -1)	return;    elf_strtab_offset = (unsigned long) pos;    elf_strtab_size = elf_strtab_output_to_file(f, objfmt_elf->strtab);    /* output .symtab - last section so all others have indexes */    if ((pos = elf_objfmt_output_align(f, 4)) == -1)	return;    elf_symtab_offset = (unsigned long) pos;    elf_symtab_size = elf_symtab_write_to_file(f, objfmt_elf->elf_symtab);    /* output section header table */    if ((pos = elf_objfmt_output_align(f, 16)) == -1)	return;    elf_shead_addr = (unsigned long) pos;    /* stabs debugging support */    if (strcmp(yasm_dbgfmt_keyword(df), "stabs")==0) {	yasm_section *stabsect = yasm_object_find_general(objfmt_elf->object,							  ".stab");	yasm_section *stabstrsect =	    yasm_object_find_general(objfmt_elf->object, ".stabstr");	if (stabsect && stabstrsect) {	    elf_secthead *stab =		yasm_section_get_data(stabsect, &elf_section_data);	    elf_secthead *stabstr =		yasm_section_get_data(stabstrsect, &elf_section_data);	    if (stab && stabstr) {		elf_secthead_set_link(stab, elf_secthead_get_index(stabstr));	    }	    else		yasm_internal_error(N_("missing .stab or .stabstr section/data"));	}    }        /* output dummy section header - 0 */    info.sindex = 0;    esdn = elf_secthead_create(NULL, SHT_NULL, 0, 0, 0, 0);    elf_secthead_write_to_file(f, esdn, 0);    elf_secthead_destroy(esdn);    esdn = elf_secthead_create(elf_shstrtab_name, SHT_STRTAB, 0, 1,			       elf_shstrtab_offset, elf_shstrtab_size);    elf_secthead_write_to_file(f, esdn, 1);    elf_secthead_destroy(esdn);    esdn = elf_secthead_create(elf_strtab_name, SHT_STRTAB, 0, 2,			       elf_strtab_offset, elf_strtab_size);    elf_secthead_write_to_file(f, esdn, 2);    elf_secthead_destroy(esdn);    esdn = elf_secthead_create(elf_symtab_name, SHT_SYMTAB, 0, 3,			       elf_symtab_offset, elf_symtab_size);    elf_secthead_set_info(esdn, elf_symtab_nlocal);    elf_secthead_set_link(esdn, 2);	/* for .strtab, which is index 2 */    elf_secthead_write_to_file(f, esdn, 3);    elf_secthead_destroy(esdn);    info.sindex = 3;    /* output remaining section headers */    yasm_object_sections_traverse(objfmt_elf->object, &info,				  elf_objfmt_output_secthead);    /* output Ehdr */    if (fseek(f, 0, SEEK_SET) < 0) {	yasm__error(0, N_("could not seek on output file"));	return;    }    elf_proghead_write_to_file(f, elf_shead_addr, info.sindex+1, 1);}static voidelf_objfmt_destroy(yasm_objfmt *objfmt){    yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt;    elf_symtab_destroy(objfmt_elf->elf_symtab);    elf_strtab_destroy(objfmt_elf->shstrtab);    elf_strtab_destroy(objfmt_elf->strtab);    yasm_xfree(objfmt);}static /*@observer@*/ /*@null@*/ yasm_section *elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,			  /*@unused@*/ /*@null@*/			  yasm_valparamhead *objext_valparams,			  unsigned long line){    yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt;    yasm_valparam *vp = yasm_vps_first(valparams);    yasm_section *retval;    int isnew;    unsigned long type = SHT_PROGBITS;    unsigned long flags = SHF_ALLOC;    unsigned long align = 4;    yasm_intnum *align_intn = NULL;    int flags_override = 0;    char *sectname;    int resonly = 0;    static const struct {	const char *name;	unsigned long flags;    } flagquals[] = {	{ "alloc",	SHF_ALLOC },	{ "exec",	SHF_EXECINSTR },	{ "write",	SHF_WRITE },	/*{ "progbits",	SHT_PROGBITS },*/	/*{ "align",	0 } */    };    if (!vp || vp->param || !vp->val)	return NULL;    sectname = vp->val;    if (strcmp(sectname, ".bss") == 0) {	type = SHT_NOBITS;	flags = SHF_ALLOC + SHF_WRITE;	resonly = 1;    } else if (strcmp(sectname, ".data") == 0) {	type = SHT_PROGBITS;	flags = SHF_ALLOC + SHF_WRITE;    } else if (strcmp(sectname, ".rodata") == 0) {	type = SHT_PROGBITS;	flags = SHF_ALLOC;    } else if (strcmp(sectname, ".text") == 0) {	align = 16;	type = SHT_PROGBITS;	flags = SHF_ALLOC + SHF_EXECINSTR;    } else {	/* Default to code */	align = 1;    }    while ((vp = yasm_vps_next(vp))) {	size_t i;	int match;	match = 0;	for (i=0; i<NELEMS(flagquals) && !match; i++) {	    if (yasm__strcasecmp(vp->val, flagquals[i].name) == 0) {		flags_override = 1;		match = 1;		flags |= flagquals[i].flags;	    }	    else if (yasm__strcasecmp(vp->val+2, flagquals[i].name) == 0		  && yasm__strncasecmp(vp->val, "no", 2) == 0) {		flags &= ~flagquals[i].flags;		flags_override = 1;		match = 1;	    }	}	if (match)	    ;	else if (yasm__strcasecmp(vp->val, "progbits") == 0) {	    type |= SHT_PROGBITS;	}	else if (yasm__strcasecmp(vp->val, "noprogbits") == 0) {	    type &= ~SHT_PROGBITS;	}	else if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) {            /*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;            unsigned long addralign;            align_expr = yasm_expr_get_intnum(&vp->param, NULL);            if (!align_expr) {                yasm__error(line,                            N_("argument to `%s' is not a power of two"),                            vp->val);                return NULL;            }            addralign = yasm_intnum_get_uint(align_expr);            /* Alignments must be a power of two. */            if ((addralign & (addralign - 1)) != 0) {                yasm__error(line,                            N_("argument to `%s' is not a power of two"),                            vp->val);                return NULL;            }            align_intn = yasm_intnum_copy(align_expr);	} else	    yasm__warning(YASM_WARN_GENERAL, line,			  N_("Unrecognized qualifier `%s'"), vp->val);    }    retval = yasm_object_get_general(objfmt_elf->object, sectname, 0, resonly,				     &isnew, line);    if (isnew) {	elf_secthead *esd;	yasm_symrec *sym;	elf_strtab_entry *name = elf_strtab_append_str(objfmt_elf->shstrtab,						       sectname);	esd = elf_secthead_create(name, type, flags, objfmt_elf->parse_scnum++,				  0, 0);	if (!align_intn)	    align_intn = yasm_intnum_create_uint(align);	if (align_intn)	    elf_secthead_set_align(esd, align_intn);	yasm_section_add_data(retval, &elf_section_data, esd);	sym = yasm_symtab_define_label(	    yasm_object_get_symtab(objfmt_elf->object), sectname,	    yasm_section_bcs_first(retval), 1, line);	elf_secthead_set_sym(esd, sym);    } else if (flags_override)	yasm__warning(YASM_WARN_GENERAL, line,		      N_("section flags ignored on section redeclaration"));    return retval;}static yasm_symrec *elf_objfmt_extern_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/			  /*@null@*/ yasm_valparamhead *objext_valparams,			  unsigned long line){    yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt;    yasm_symrec *sym;    sym = yasm_symtab_declare(objfmt_elf->symtab, name, YASM_SYM_EXTERN, line);    elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_GLOBAL,			     STT_NOTYPE, NULL, 0);    return sym;}static yasm_symrec *elf_objfmt_global_declare(yasm_objfmt *objfmt, const char *name,			  /*@null@*/ yasm_valparamhead *objext_valparams,			  unsigned long line){    yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt;    yasm_symrec *sym;    elf_symbol_type type = STT_NOTYPE;    yasm_expr *size = NULL;    sym = yasm_symtab_declare(objfmt_elf->symtab, name, YASM_SYM_GLOBAL, line);    if (objext_valparams) {	yasm_valparam *vp = yasm_vps_first(objext_valparams);	if (vp && vp->val) {	    if (yasm__strcasecmp(vp->val, "function") == 0)		type = STT_FUNC;	    else if (yasm__strcasecmp(vp->val, "data") == 0 ||		     yasm__strcasecmp(vp->val, "object") == 0)		type = STT_OBJECT;	    else		yasm__error(line, N_("unrecognized symbol type `%s'"),			    vp->val);	    vp = yasm_vps_next(vp);	}	if (vp && !vp->val && vp->param) {	    size = vp->param;	    vp->param = NULL;	/* to avoid deleting the expr */	}    }    elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_GLOBAL,			     type, size, 0);    return sym;}static yasm_symrec *elf_objfmt_common_declare(yasm_objfmt *objfmt, const char *name,			  /*@only@*/ yasm_expr *size, /*@null@*/			  yasm_valparamhead *objext_valparams,			  unsigned long line){    yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt;    yasm_symrec *sym;    unsigned long addralign = 0;    sym = yasm_symtab_declare(objfmt_elf->symtab, name, YASM_SYM_COMMON, line);    if (objext_valparams) {	yasm_valparam *vp = yasm_vps_first(objext_valparams);	if (vp && !vp->val && vp->param) {            /*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;            align_expr = yasm_expr_get_intnum(&vp->param, NULL);            if (!align_expr) {                yasm__error(line,                            N_("alignment constraint is not a power of two"));                return sym;            }            addralign = yasm_intnum_get_uint(align_expr);            /* Alignments must be a power of two. */            if ((addralign & (addralign - 1)) != 0) {                yasm__error(line,                            N_("alignment constraint is not a power of two"));                return sym;            }	} else if (vp && vp->val)	    yasm__warning(YASM_WARN_GENERAL, line,			  N_("Unrecognized qualifier `%s'"), vp->val);    }    elf_objfmt_symtab_append(objfmt_elf, sym, SHN_COMMON, STB_GLOBAL,			     STT_NOTYPE, size, addralign);    return sym;}static intelf_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 *elf_objfmt_dbgfmt_keywords[] = {    "null",    "stabs",    NULL};/* Define objfmt structure -- see objfmt.h for details */yasm_objfmt_module yasm_elf_LTX_objfmt = {    YASM_OBJFMT_VERSION,    "ELF",    "elf",    "o",    ".text",    32,    elf_objfmt_dbgfmt_keywords,    "null",    elf_objfmt_create,    elf_objfmt_output,    elf_objfmt_destroy,    elf_objfmt_section_switch,    elf_objfmt_extern_declare,    elf_objfmt_global_declare,    elf_objfmt_common_declare,    elf_objfmt_directive};

⌨️ 快捷键说明

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