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

📄 elf.c

📁 支持AMD64的汇编编译器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		yasm__error(entry->xsize->line,		    N_("size specifier not an integer expression"));	}	else	    size_intn = yasm_intnum_create_uint(entry->size);	/* get EQU value for constants */	if (entry->sym) {	    const yasm_expr *equ_expr_c;	    equ_expr_c = yasm_symrec_get_equ(entry->sym);	    if (equ_expr_c != NULL) {		const yasm_intnum *equ_intn;		yasm_expr *equ_expr = yasm_expr_copy(equ_expr_c);		equ_intn = yasm_expr_get_intnum(&equ_expr,						yasm_common_calc_bc_dist);		if (equ_intn == NULL) {		    yasm__error(equ_expr->line,				N_("EQU value not an integer expression"));		}		value_intn = yasm_intnum_copy(equ_intn);		entry->index = SHN_ABS;		yasm_expr_destroy(equ_expr);	    }	}	if (value_intn == NULL)	    value_intn = yasm_intnum_create_uint(entry->value);        if (!elf_march->write_symtab_entry || !elf_march->symtab_entry_size)            yasm_internal_error(N_("Unsupported machine for ELF output"));        elf_march->write_symtab_entry(bufp, entry, value_intn, size_intn);        fwrite(buf, elf_march->symtab_entry_size, 1, f);        size += elf_march->symtab_entry_size;	yasm_intnum_destroy(size_intn);	yasm_intnum_destroy(value_intn);	prev = entry;    }    return size;}void elf_symtab_set_nonzero(elf_symtab_entry *entry,			    yasm_section *sect,			    elf_section_index sectidx,			    elf_symbol_binding bind,			    elf_symbol_type type,			    yasm_expr *xsize,			    elf_address value){    if (!entry)	yasm_internal_error("NULL entry");    if (sect) entry->sect = sect;    if (sectidx) entry->index = sectidx;    if (bind) entry->bind = bind;    if (type) entry->type = type;    if (xsize) entry->xsize = xsize;    if (value) entry->value = value;}elf_secthead *elf_secthead_create(elf_strtab_entry	*name,		    elf_section_type	 type,		    elf_section_flags	 flags,		    elf_section_index	 idx,		    elf_address		 offset,		    elf_size		 size){    elf_secthead *esd = yasm_xmalloc(sizeof(elf_secthead));    esd->type = type;    esd->flags = flags;    esd->offset = offset;    esd->size = yasm_intnum_create_uint(size);    esd->link = 0;    esd->info = 0;    esd->align = NULL;    esd->entsize = 0;    esd->index = idx;    esd->sym = NULL;    esd->name = name;    esd->index = 0;    esd->rel_name = NULL;    esd->rel_index = idx;    esd->rel_offset = 0;    esd->nreloc = 0;    if (name && (strcmp(name->str, ".symtab") == 0)) {        if (!elf_march->symtab_entry_size || !elf_march->symtab_entry_align)	    yasm_internal_error(N_("unsupported ELF format"));        esd->entsize = elf_march->symtab_entry_size;        esd->align = yasm_intnum_create_uint(elf_march->symtab_entry_align);    }    return esd;}voidelf_secthead_destroy(elf_secthead *shead){    if (shead == NULL)	yasm_internal_error(N_("shead is null"));    if (shead->align)	yasm_intnum_destroy(shead->align);    yasm_xfree(shead);}static voidelf_section_data_destroy(void *data){    elf_secthead_destroy((elf_secthead *)data);}static voidelf_secthead_print(void *data, FILE *f, int indent_level){    elf_secthead *sect = data;    fprintf(f, "%*sname=%s\n", indent_level, "",	    sect->name ? sect->name->str : "<undef>");    fprintf(f, "%*ssym=\n", indent_level, "");    yasm_symrec_print(sect->sym, f, indent_level+1);    fprintf(f, "%*sindex=0x%x\n", indent_level, "", sect->index);    fprintf(f, "%*sflags=", indent_level, "");    if (sect->flags & SHF_WRITE)	fprintf(f, "WRITE ");    if (sect->flags & SHF_ALLOC)	fprintf(f, "ALLOC ");    if (sect->flags & SHF_EXECINSTR)	fprintf(f, "EXEC ");    /*if (sect->flags & SHF_MASKPROC)	fprintf(f, "PROC-SPECIFIC"); */    fprintf(f, "%*soffset=0x%lx\n", indent_level, "", sect->offset);    fprintf(f, "%*ssize=0x%lx\n", indent_level, "",	    yasm_intnum_get_uint(sect->size));    fprintf(f, "%*slink=0x%x\n", indent_level, "", sect->link);    fprintf(f, "%*salign=%ld\n", indent_level, "",	    yasm_intnum_get_uint(sect->align));    fprintf(f, "%*snreloc=%ld\n", indent_level, "", sect->nreloc);}unsigned longelf_secthead_write_to_file(FILE *f, elf_secthead *shead,			   elf_section_index sindex){    unsigned char buf[SHDR_MAXSIZE], *bufp = buf;    shead->index = sindex;    if (shead == NULL)	yasm_internal_error("shead is null");    if (!elf_march->write_secthead || !elf_march->secthead_size)        yasm_internal_error(N_("Unsupported machine for ELF output"));    elf_march->write_secthead(bufp, shead);    if (fwrite(buf, elf_march->secthead_size, 1, f))        return elf_march->secthead_size;    yasm_internal_error(N_("Failed to write an elf section header"));    return 0;}intelf_secthead_append_reloc(yasm_section *sect, elf_secthead *shead,			  elf_reloc_entry *reloc){    int new_sect = 0;    if (sect == NULL)	yasm_internal_error("sect is null");    if (shead == NULL)	yasm_internal_error("shead is null");    if (reloc == NULL)	yasm_internal_error("reloc is null");    shead->nreloc++;    yasm_section_add_reloc(sect, (yasm_reloc *)reloc, elf_reloc_entry_destroy);    return new_sect;}char *elf_secthead_name_reloc_section(const char *basesect){    if (!elf_march->reloc_section_prefix)    {        yasm_internal_error(N_("Unsupported machine for ELF output"));        return NULL;    }    else    {        int prepend_length = strlen(elf_march->reloc_section_prefix);        char *sectname = yasm_xmalloc(prepend_length + strlen(basesect) + 1);        strcpy(sectname, elf_march->reloc_section_prefix);        strcat(sectname, basesect);        return sectname;    }}voidelf_handle_reloc_addend(yasm_intnum *intn, elf_reloc_entry *reloc){    if (!elf_march->handle_reloc_addend)        yasm_internal_error(N_("Unsupported machine for ELF output"));    elf_march->handle_reloc_addend(intn, reloc);}unsigned longelf_secthead_write_rel_to_file(FILE *f, elf_section_index symtab_idx,			       yasm_section *sect, elf_secthead *shead,			       elf_section_index sindex){    unsigned char buf[SHDR_MAXSIZE], *bufp = buf;    if (shead == NULL)	yasm_internal_error("shead is null");    if (!yasm_section_relocs_first(sect))	return 0;  	/* no relocations, no .rel.* section header */    shead->rel_index = sindex;    if (!elf_march->write_secthead_rel || !elf_march->secthead_size)        yasm_internal_error(N_("Unsupported machine for ELF output"));    elf_march->write_secthead_rel(bufp, shead, symtab_idx, sindex);    if (fwrite(buf, elf_march->secthead_size, 1, f))        return elf_march->secthead_size;    yasm_internal_error(N_("Failed to write an elf section header"));    return 0;}unsigned longelf_secthead_write_relocs_to_file(FILE *f, yasm_section *sect,				  elf_secthead *shead){    elf_reloc_entry *reloc;    unsigned char buf[RELOC_MAXSIZE], *bufp;    unsigned long size = 0;    long pos;    if (shead == NULL)	yasm_internal_error("shead is null");    reloc = (elf_reloc_entry *)yasm_section_relocs_first(sect);    if (!reloc)	return 0;    /* first align section to multiple of 4 */    pos = ftell(f);    if (pos == -1)	yasm__error(0, N_("couldn't read position on output stream"));    pos = (pos + 3) & ~3;    if (fseek(f, pos, SEEK_SET) < 0)	yasm__error(0, N_("couldn't seek on output stream"));    shead->rel_offset = (unsigned long)pos;    while (reloc) {	yasm_sym_vis vis;	unsigned int r_type=0, r_sym;	elf_symtab_entry *esym;	esym = yasm_symrec_get_data(reloc->reloc.sym, &elf_symrec_data);	if (esym)	    r_sym = esym->symindex;	else	    r_sym = STN_UNDEF;	vis = yasm_symrec_get_visibility(reloc->reloc.sym);        if (!elf_march->map_reloc_info_to_type)            yasm_internal_error(N_("Unsupported arch/machine for elf output"));        r_type = elf_march->map_reloc_info_to_type(reloc, elf_ssyms);	bufp = buf;        if (!elf_march->write_reloc || !elf_march->reloc_entry_size)            yasm_internal_error(N_("Unsupported arch/machine for elf output"));        elf_march->write_reloc(bufp, reloc, r_type, r_sym);        fwrite(buf, elf_march->reloc_entry_size, 1, f);        size += elf_march->reloc_entry_size;	reloc = (elf_reloc_entry *)	    yasm_section_reloc_next((yasm_reloc *)reloc);    }    return size;}elf_section_typeelf_secthead_get_type(elf_secthead *shead){    return shead->type;}intelf_secthead_is_empty(elf_secthead *shead){    return yasm_intnum_is_zero(shead->size);}yasm_symrec *elf_secthead_get_sym(elf_secthead *shead){    return shead->sym;}elf_section_indexelf_secthead_get_index(elf_secthead *shead){    return shead->index;}const yasm_intnum *elf_secthead_set_align(elf_secthead *shead, yasm_intnum *align){    if (shead->align != NULL)	yasm_intnum_destroy(shead->align);        return shead->align = align;}elf_section_infoelf_secthead_set_info(elf_secthead *shead, elf_section_info info){    return shead->info = info;}elf_section_indexelf_secthead_set_index(elf_secthead *shead, elf_section_index sectidx){    return shead->index = sectidx;}elf_section_indexelf_secthead_set_link(elf_secthead *shead, elf_section_index link){    return shead->link = link;}elf_section_indexelf_secthead_set_rel_index(elf_secthead *shead, elf_section_index sectidx){    return shead->rel_index = sectidx;}elf_strtab_entry *elf_secthead_set_rel_name(elf_secthead *shead, elf_strtab_entry *entry){    return shead->rel_name = entry;}elf_sizeelf_secthead_set_entsize(elf_secthead *shead, elf_size size){    return shead->entsize = size;}yasm_symrec *elf_secthead_set_sym(elf_secthead *shead, yasm_symrec *sym){    return shead->sym = sym;}voidelf_secthead_add_size(elf_secthead *shead, yasm_intnum *size){    if (size) {	yasm_intnum_calc(shead->size, YASM_EXPR_ADD, size, 0);    }}longelf_secthead_set_file_offset(elf_secthead *shead, long pos){    unsigned long align = yasm_intnum_get_uint(shead->align);    if (align == 0 || align == 1) {	shead->offset = (unsigned long)pos;	return pos;    }    else if (align & (align - 1))	yasm_internal_error(	    N_("alignment %d for section `%s' is not a power of 2"));	    /*, align, sect->name->str);*/    shead->offset = (unsigned long)((pos + align - 1) & ~(align - 1));    return (long)shead->offset;}unsigned longelf_proghead_get_size(void){    if (!elf_march->proghead_size)	yasm_internal_error(N_("Unsupported ELF format for output"));    return elf_march->proghead_size;}unsigned longelf_proghead_write_to_file(FILE *f,			   elf_offset secthead_addr,			   unsigned long secthead_count,			   elf_section_index shstrtab_index){    unsigned char buf[EHDR_MAXSIZE], *bufp = buf;    YASM_WRITE_8(bufp, ELFMAG0);		/* ELF magic number */    YASM_WRITE_8(bufp, ELFMAG1);    YASM_WRITE_8(bufp, ELFMAG2);    YASM_WRITE_8(bufp, ELFMAG3);    if (!elf_march->write_proghead || !elf_march->proghead_size)	yasm_internal_error(N_("Unsupported ELF format for output"));    elf_march->write_proghead(&bufp, secthead_addr, secthead_count, shstrtab_index);    if (((unsigned)(bufp - buf)) != elf_march->proghead_size)        yasm_internal_error(N_("ELF program header is not proper length"));    if (fwrite(buf, elf_march->proghead_size, 1, f))        return elf_march->proghead_size;    yasm_internal_error(N_("Failed to write ELF program header"));    return 0;}

⌨️ 快捷键说明

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