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

📄 nasm-listfmt.c

📁 支持AMD64的汇编编译器源码
💻 C
字号:
/* * NASM-style list format * *  Copyright (C) 2004  Peter Johnson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */#include <util.h>/*@unused@*/ RCSID("$Id: nasm-listfmt.c 1168 2004-10-31 01:07:52Z peter $");#define YASM_LIB_INTERNAL#define YASM_BC_INTERNAL#include <libyasm.h>/* NOTE: For this code to generate relocation information, the relocations * have to be added by the object format to each section in program source * order. * * This should not be an issue, as program source order == section bytecode * order, so unless the object formats are very obtuse with their bytecode * iteration, this should just happen. */#define REGULAR_BUF_SIZE    1024yasm_listfmt_module yasm_nasm_LTX_listfmt;typedef struct sectreloc {    /*@reldef@*/ SLIST_ENTRY(sectreloc) link;    yasm_section *sect;    /*@null@*/ yasm_reloc *next_reloc;	/* next relocation in section */    unsigned long next_reloc_addr;} sectreloc;typedef struct bcreloc {    /*@reldef@*/ STAILQ_ENTRY(bcreloc) link;    unsigned long offset;	/* start of reloc from start of bytecode */    size_t size;		/* size of reloc in bytes */    int rel;			/* PC/IP-relative or "absolute" */} bcreloc;typedef struct nasm_listfmt_output_info {    yasm_arch *arch;    /*@reldef@*/ STAILQ_HEAD(bcrelochead, bcreloc) bcrelocs;    /*@null@*/ yasm_reloc *next_reloc;	/* next relocation in section */    unsigned long next_reloc_addr;} nasm_listfmt_output_info;static /*@null@*/ /*@only@*/ yasm_listfmt *nasm_listfmt_create(const char *in_filename, const char *obj_filename){    yasm_listfmt_base *listfmt = yasm_xmalloc(sizeof(yasm_listfmt_base));    listfmt->module = &yasm_nasm_LTX_listfmt;    return (yasm_listfmt *)listfmt;}static voidnasm_listfmt_destroy(/*@only@*/ yasm_listfmt *listfmt){    yasm_xfree(listfmt);}static intnasm_listfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,			 size_t valsize, int shift, unsigned long offset,			 yasm_bytecode *bc, int rel, int warn,			 /*@null@*/ void *d){    /*@null@*/ nasm_listfmt_output_info *info = (nasm_listfmt_output_info *)d;    /*@dependent@*/ /*@null@*/ yasm_intnum *intn;    /*@dependent@*/ /*@null@*/ const yasm_floatnum *flt;    assert(info != NULL);    /* Generate reloc if needed */    if (info->next_reloc && info->next_reloc_addr == bc->offset+offset) {	bcreloc *reloc = yasm_xmalloc(sizeof(bcreloc));	reloc->offset = offset;	reloc->size = destsize;	reloc->rel = rel;	STAILQ_INSERT_TAIL(&info->bcrelocs, reloc, link);	/* Get next reloc's info */	info->next_reloc = yasm_section_reloc_next(info->next_reloc);	if (info->next_reloc) {	    yasm_intnum *addr;	    yasm_symrec *sym;	    yasm_reloc_get(info->next_reloc, &addr, &sym);	    info->next_reloc_addr = yasm_intnum_get_uint(addr);	}    }    flt = yasm_expr_get_floatnum(ep);    if (flt) {	if (shift < 0)	    yasm_internal_error(N_("attempting to negative shift a float"));	return yasm_arch_floatnum_tobytes(info->arch, flt, buf, destsize,					  valsize, (unsigned int)shift, 0,					  bc->line);    }    intn = yasm_expr_get_intnum(ep, NULL);    if (intn)	return yasm_arch_intnum_tobytes(info->arch, intn, buf, destsize,					valsize, shift, bc, 0, bc->line);    return 0;}static voidnasm_listfmt_output(yasm_listfmt *listfmt, FILE *f, yasm_linemap *linemap,		    yasm_arch *arch){    yasm_bytecode *bc;    const char *source;    unsigned long line = 1;    unsigned long listline = 1;    /*@only@*/ unsigned char *buf;    nasm_listfmt_output_info info;    /*@reldef@*/ SLIST_HEAD(sectrelochead, sectreloc) reloc_hist;    /*@null@*/ sectreloc *last_hist = NULL;    /*@null@*/ bcreloc *reloc = NULL;    yasm_section *sect;    SLIST_INIT(&reloc_hist);    info.arch = arch;    buf = yasm_xmalloc(REGULAR_BUF_SIZE);    while (!yasm_linemap_get_source(linemap, line, &bc, &source)) {	if (!bc) {	    fprintf(f, "%6lu %*s%s\n", listline++, 32, "", source);	} else {	    /* get the next relocation for the bytecode's section */	    sect = yasm_bc_get_section(bc);	    if (!last_hist || last_hist->sect != sect) {		int found = 0;		/* look through reloc_hist for matching section */		SLIST_FOREACH(last_hist, &reloc_hist, link) {		    if (last_hist->sect == sect) {			found = 1;			break;		    }		}		if (!found) {		    /* not found, add to list*/		    last_hist = yasm_xmalloc(sizeof(sectreloc));		    last_hist->sect = sect;		    last_hist->next_reloc = yasm_section_relocs_first(sect);		    if (last_hist->next_reloc) {			yasm_intnum *addr;			yasm_symrec *sym;			yasm_reloc_get(last_hist->next_reloc, &addr, &sym);			last_hist->next_reloc_addr =			    yasm_intnum_get_uint(addr);		    }		    SLIST_INSERT_HEAD(&reloc_hist, last_hist, link);		}	    }	    info.next_reloc = last_hist->next_reloc;	    info.next_reloc_addr = last_hist->next_reloc_addr;	    STAILQ_INIT(&info.bcrelocs);	    /* loop over bytecodes on this line (usually only one) */	    while (bc && bc->line == line) {		/*@null@*/ /*@only@*/ unsigned char *bigbuf;		unsigned long size = REGULAR_BUF_SIZE;		unsigned long multiple;		unsigned long offset = bc->offset;		unsigned char *origp, *p;		int gap;		/* convert bytecode into bytes, recording relocs along the		 * way		 */		bigbuf = yasm_bc_tobytes(bc, buf, &size, &multiple, &gap,					 &info, nasm_listfmt_output_expr,					 NULL);		/* output bytes with reloc information */		origp = bigbuf ? bigbuf : buf;		p = origp;		reloc = STAILQ_FIRST(&info.bcrelocs);		if (gap) {		    fprintf(f, "%6lu %08lX <gap>%*s%s\n", listline++, offset,			    18, "", source ? source : "");		} else while (size > 0) {		    int i;		    fprintf(f, "%6lu %08lX ", listline++, offset);		    for (i=0; i<18 && size > 0; size--) {			if (reloc && (unsigned long)(p-origp) ==				     reloc->offset) {			    fprintf(f, "%c", reloc->rel ? '(' : '[');			    i++;			}			fprintf(f, "%02X", *(p++));			i+=2;			if (reloc && (unsigned long)(p-origp) ==				     reloc->offset+reloc->size) {			    fprintf(f, "%c", reloc->rel ? ')' : ']');			    i++;			    reloc = STAILQ_NEXT(reloc, link);			}		    }		    if (size > 0)			fprintf(f, "-");		    else {			if (multiple > 1) {			    fprintf(f, "<rept>");			    i += 6;			}			fprintf(f, "%*s", 18-i+1, "");		    }		    if (source) {			fprintf(f, "    %s", source);			source = NULL;		    }		    fprintf(f, "\n");		}		if (bigbuf)		    yasm_xfree(bigbuf);		bc = STAILQ_NEXT(bc, link);	    }	    /* delete bcrelocs (newly generated next bytecode if any) */	    reloc = STAILQ_FIRST(&info.bcrelocs);	    while (reloc) {		bcreloc *reloc2 = STAILQ_NEXT(reloc, link);		yasm_xfree(reloc);		reloc = reloc2;	    }	    /* save reloc context */	    last_hist->next_reloc = info.next_reloc;	    last_hist->next_reloc_addr = info.next_reloc_addr;	}	line++;    }    /* delete reloc history */    while (!SLIST_EMPTY(&reloc_hist)) {	last_hist = SLIST_FIRST(&reloc_hist);	SLIST_REMOVE_HEAD(&reloc_hist, link);	yasm_xfree(last_hist);    }    yasm_xfree(buf);}/* Define listfmt structure -- see listfmt.h for details */yasm_listfmt_module yasm_nasm_LTX_listfmt = {    YASM_LISTFMT_VERSION,    "NASM-style list format",    "nasm",    nasm_listfmt_create,    nasm_listfmt_destroy,    nasm_listfmt_output};

⌨️ 快捷键说明

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