145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ORG bytecode 345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Copyright (C) 2005-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-stdint.h" 3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "coretype.h" 3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "file.h" 3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "errwarn.h" 3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "intnum.h" 3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "expr.h" 3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "value.h" 3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "bytecode.h" 3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct bytecode_org { 4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long start; /* target starting offset within section */ 4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long fill; /* fill value */ 4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} bytecode_org; 4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void bc_org_destroy(void *contents); 4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void bc_org_print(const void *contents, FILE *f, int indent_level); 4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void bc_org_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc); 4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int bc_org_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, 5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org void *add_span_data); 5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int bc_org_expand(yasm_bytecode *bc, int span, long old_val, 5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org long new_val, /*@out@*/ long *neg_thres, 5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@out@*/ long *pos_thres); 54d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orgstatic int bc_org_tobytes(yasm_bytecode *bc, unsigned char **bufp, 55d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org unsigned char *bufstart, void *d, 5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_output_value_func output_value, 5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ yasm_output_reloc_func output_reloc); 5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_bytecode_callback bc_org_callback = { 6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc_org_destroy, 6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc_org_print, 6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc_org_finalize, 6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL, 6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc_org_calc_len, 6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc_org_expand, 6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc_org_tobytes, 6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org YASM_BC_SPECIAL_OFFSET 6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbc_org_destroy(void *contents) 7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(contents); 7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbc_org_print(const void *contents, FILE *f, int indent_level) 7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const bytecode_org *org = (const bytecode_org *)contents; 8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*s_Org_\n", indent_level, ""); 8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*sStart=%lu\n", indent_level, "", org->start); 8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbc_org_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc) 8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbc_org_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, 9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org void *add_span_data) 9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bytecode_org *org = (bytecode_org *)bc->contents; 9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org long neg_thres = 0; 9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org long pos_thres = org->start; 9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bc_org_expand(bc, 0, 0, (long)bc->offset, &neg_thres, &pos_thres) < 0) 9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbc_org_expand(yasm_bytecode *bc, int span, long old_val, long new_val, 10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres) 10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bytecode_org *org = (bytecode_org *)bc->contents; 10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Check for overrun */ 11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((unsigned long)new_val > org->start) { 11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_GENERAL, 11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("ORG overlap with already existing data")); 11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Generate space to start offset */ 11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc->len = org->start - new_val; 11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 123d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orgbc_org_tobytes(yasm_bytecode *bc, unsigned char **bufp, 124d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org unsigned char *bufstart, void *d, 12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_output_value_func output_value, 12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@unused@*/ yasm_output_reloc_func output_reloc) 12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bytecode_org *org = (bytecode_org *)bc->contents; 12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long len, i; 13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Sanity check for overrun */ 13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bc->offset > org->start) { 13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_GENERAL, 13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("ORG overlap with already existing data")); 13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = org->start - bc->offset; 13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<len; i++) 13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org YASM_WRITE_8(*bufp, org->fill); /* XXX: handle more than 8 bit? */ 14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_bytecode * 14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_bc_create_org(unsigned long start, unsigned long fill, unsigned long line) 14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bytecode_org *org = yasm_xmalloc(sizeof(bytecode_org)); 14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org org->start = start; 14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org org->fill = fill; 15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return yasm_bc_create_common(&bc_org_callback, org, line); 15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 153