145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * NASM-style list format 345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Copyright (C) 2004-2007 Peter Johnson 545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Redistribution and use in source and binary forms, with or without 745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * modification, are permitted provided that the following conditions 845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are met: 945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1. Redistributions of source code must retain the above copyright 1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * notice, this list of conditions and the following disclaimer. 1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * notice, this list of conditions and the following disclaimer in the 1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * documentation and/or other materials provided with the distribution. 1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE. 2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <util.h> 2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <libyasm.h> 3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* NOTE: For this code to generate relocation information, the relocations 3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * have to be added by the object format to each section in program source 3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * order. 3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This should not be an issue, as program source order == section bytecode 3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * order, so unless the object formats are very obtuse with their bytecode 3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * iteration, this should just happen. 3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define REGULAR_BUF_SIZE 1024 4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_listfmt_module yasm_nasm_LTX_listfmt; 4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct sectreloc { 4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@reldef@*/ SLIST_ENTRY(sectreloc) link; 4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *sect; 4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ yasm_reloc *next_reloc; /* next relocation in section */ 4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long next_reloc_addr; 4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} sectreloc; 5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct bcreloc { 5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@reldef@*/ STAILQ_ENTRY(bcreloc) link; 5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long offset; /* start of reloc from start of bytecode */ 5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t size; /* size of reloc in bytes */ 5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int rel; /* PC/IP-relative or "absolute" */ 5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} bcreloc; 5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct nasm_listfmt_output_info { 5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_arch *arch; 6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@reldef@*/ STAILQ_HEAD(bcrelochead, bcreloc) bcrelocs; 6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ yasm_reloc *next_reloc; /* next relocation in section */ 6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long next_reloc_addr; 6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} nasm_listfmt_output_info; 6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@null@*/ /*@only@*/ yasm_listfmt * 6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_listfmt_create(const char *in_filename, const char *obj_filename) 6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_listfmt_base *listfmt = yasm_xmalloc(sizeof(yasm_listfmt_base)); 7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org listfmt->module = &yasm_nasm_LTX_listfmt; 7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (yasm_listfmt *)listfmt; 7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_listfmt_destroy(/*@only@*/ yasm_listfmt *listfmt) 7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(listfmt); 7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_listfmt_output_value(yasm_value *value, unsigned char *buf, 8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int destsize, unsigned long offset, 8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bytecode *bc, int warn, /*@null@*/ void *d) 8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ nasm_listfmt_output_info *info = (nasm_listfmt_output_info *)d; 8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ /*@null@*/ yasm_intnum *intn; 8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int valsize = value->size; 8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Output */ 9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (yasm_value_output_basic(value, buf, destsize, bc, warn, 9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->arch)) { 9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case -1: 9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 0: 9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Generate reloc if needed */ 10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (info->next_reloc && info->next_reloc_addr == bc->offset+offset) { 10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bcreloc *reloc = yasm_xmalloc(sizeof(bcreloc)); 10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org reloc->offset = offset; 10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org reloc->size = destsize; 10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org reloc->rel = value->curpos_rel; 10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_INSERT_TAIL(&info->bcrelocs, reloc, link); 10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Get next reloc's info */ 11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->next_reloc = yasm_section_reloc_next(info->next_reloc); 11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (info->next_reloc) { 11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *addr; 11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec *sym; 11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_reloc_get(info->next_reloc, &addr, &sym); 11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->next_reloc_addr = yasm_intnum_get_uint(addr); 11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (value->abs) { 12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_expr_get_intnum(&value->abs, 0); 12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (intn) 12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return yasm_arch_intnum_tobytes(info->arch, intn, buf, destsize, 12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org valsize, 0, bc, 0); 12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else { 12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TOO_COMPLEX, 12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("relocation too complex")); 12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int retval; 13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_intnum_create_uint(0); 13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval = yasm_arch_intnum_tobytes(info->arch, intn, buf, destsize, 13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org valsize, 0, bc, 0); 13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(intn); 13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return retval; 13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_listfmt_output(yasm_listfmt *listfmt, FILE *f, yasm_linemap *linemap, 14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_arch *arch) 14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bytecode *bc; 14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *source; 14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long line = 1; 14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long listline = 1; 15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ unsigned char *buf; 15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_listfmt_output_info info; 15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@reldef@*/ SLIST_HEAD(sectrelochead, sectreloc) reloc_hist; 15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ sectreloc *last_hist = NULL; 15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ bcreloc *reloc = NULL; 15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *sect; 15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SLIST_INIT(&reloc_hist); 15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.arch = arch; 16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org buf = yasm_xmalloc(REGULAR_BUF_SIZE); 16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (!yasm_linemap_get_source(linemap, line, &bc, &source)) { 16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!bc) { 16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%6lu %*s%s\n", listline++, 32, "", source); 16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* get the next relocation for the bytecode's section */ 16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sect = yasm_bc_get_section(bc); 16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!last_hist || last_hist->sect != sect) { 17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int found = 0; 17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* look through reloc_hist for matching section */ 17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SLIST_FOREACH(last_hist, &reloc_hist, link) { 17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (last_hist->sect == sect) { 17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org found = 1; 17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!found) { 18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* not found, add to list*/ 18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last_hist = yasm_xmalloc(sizeof(sectreloc)); 18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last_hist->sect = sect; 18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last_hist->next_reloc = yasm_section_relocs_first(sect); 18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (last_hist->next_reloc) { 18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *addr; 18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec *sym; 18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_reloc_get(last_hist->next_reloc, &addr, &sym); 19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last_hist->next_reloc_addr = 19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_get_uint(addr); 19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SLIST_INSERT_HEAD(&reloc_hist, last_hist, link); 19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.next_reloc = last_hist->next_reloc; 19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.next_reloc_addr = last_hist->next_reloc_addr; 20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_INIT(&info.bcrelocs); 20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* loop over bytecodes on this line (usually only one) */ 20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (bc && bc->line == line) { 20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ /*@only@*/ unsigned char *bigbuf; 20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long size = REGULAR_BUF_SIZE; 20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org long multiple; 20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long offset = bc->offset; 20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned char *origp, *p; 20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int gap; 21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* convert bytecode into bytes, recording relocs along the 21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * way 21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bigbuf = yasm_bc_tobytes(bc, buf, &size, &gap, &info, 21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_listfmt_output_value, NULL); 21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bc_get_multiple(bc, &multiple, 1); 21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (multiple <= 0) 21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = 0; 21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size /= multiple; 22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* output bytes with reloc information */ 22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org origp = bigbuf ? bigbuf : buf; 22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = origp; 22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org reloc = STAILQ_FIRST(&info.bcrelocs); 22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (gap) { 22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%6lu %08lX <gap>%*s%s\n", listline++, offset, 22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 18, "", source ? source : ""); 22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else while (size > 0) { 23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int i; 23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%6lu %08lX ", listline++, offset); 23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<18 && size > 0; size--) { 23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (reloc && (unsigned long)(p-origp) == 23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org reloc->offset) { 23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%c", reloc->rel ? '(' : '['); 23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i++; 23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%02X", *(p++)); 24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i+=2; 24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (reloc && (unsigned long)(p-origp) == 24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org reloc->offset+reloc->size) { 24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%c", reloc->rel ? ')' : ']'); 24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i++; 24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org reloc = STAILQ_NEXT(reloc, link); 24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (size > 0) 24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "-"); 25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else { 25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (multiple > 1) { 25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "<rept>"); 25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i += 6; 25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*s", 18-i+1, ""); 25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (source) { 25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, " %s", source); 25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org source = NULL; 26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n"); 26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bigbuf) 26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(bigbuf); 26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc = STAILQ_NEXT(bc, link); 26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* delete bcrelocs (newly generated next bytecode if any) */ 27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org reloc = STAILQ_FIRST(&info.bcrelocs); 27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (reloc) { 27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bcreloc *reloc2 = STAILQ_NEXT(reloc, link); 27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(reloc); 27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org reloc = reloc2; 27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* save reloc context */ 27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last_hist->next_reloc = info.next_reloc; 27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last_hist->next_reloc_addr = info.next_reloc_addr; 28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line++; 28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* delete reloc history */ 28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (!SLIST_EMPTY(&reloc_hist)) { 28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last_hist = SLIST_FIRST(&reloc_hist); 28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SLIST_REMOVE_HEAD(&reloc_hist, link); 28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(last_hist); 28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(buf); 29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Define listfmt structure -- see listfmt.h for details */ 29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_listfmt_module yasm_nasm_LTX_listfmt = { 29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "NASM-style list format", 29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "nasm", 29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_listfmt_create, 29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_listfmt_destroy, 30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_listfmt_output 30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 302