145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Data (and LEB128) bytecode 345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Copyright (C) 2001-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 3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "errwarn.h" 3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "intnum.h" 3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "expr.h" 3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "value.h" 3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "bytecode.h" 3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "arch.h" 3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct yasm_dataval { 4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@reldef@*/ STAILQ_ENTRY(yasm_dataval) link; 4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org enum { DV_EMPTY, DV_VALUE, DV_RAW, DV_ULEB128, DV_SLEB128, DV_RESERVE } 4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type; 4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org union { 4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value val; 4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct { 5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ unsigned char *contents; 5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long len; 5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } raw; 5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } data; 5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* number of times data is repeated, NULL=1. */ 5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ yasm_expr *multiple; 5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct bytecode_data { 6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* converted data (linked list) */ 6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_datavalhead datahead; 6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int item_size; 6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} bytecode_data; 6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void bc_data_destroy(void *contents); 6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void bc_data_print(const void *contents, FILE *f, int indent_level); 6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void bc_data_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc); 6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int bc_data_item_size(yasm_bytecode *bc); 7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int bc_data_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, 7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org void *add_span_data); 72d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orgstatic int bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, 73d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org unsigned char *bufstart, void *d, 7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_output_value_func output_value, 7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ yasm_output_reloc_func output_reloc); 7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_bytecode_callback bc_data_callback = { 7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc_data_destroy, 7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc_data_print, 8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc_data_finalize, 8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc_data_item_size, 8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc_data_calc_len, 8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bc_expand_common, 8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc_data_tobytes, 8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 0 8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbc_data_destroy(void *contents) 9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bytecode_data *bc_data = (bytecode_data *)contents; 9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dvs_delete(&bc_data->datahead); 9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(contents); 9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbc_data_print(const void *contents, FILE *f, int indent_level) 9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const bytecode_data *bc_data = (const bytecode_data *)contents; 10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*s_Data_\n", indent_level, ""); 10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*sElements:\n", indent_level+1, ""); 10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dvs_print(&bc_data->datahead, f, indent_level+2); 10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbc_data_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc) 10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bytecode_data *bc_data = (bytecode_data *)bc->contents; 11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dataval *dv; 11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *intn; 11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Convert values from simple expr to value. */ 11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_FOREACH(dv, &bc_data->datahead, link) { 11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (dv->type) { 11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_VALUE: 11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_value_finalize(&dv->data.val, prev_bc)) { 11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TOO_COMPLEX, 11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("data expression too complex")); 12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_ULEB128: 12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_SLEB128: 12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_expr_get_intnum(&dv->data.val.abs, 0); 12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!intn) { 12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_NOT_CONSTANT, 12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("LEB128 requires constant values")); 12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Warn for negative values in unsigned environment. 13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This could be an error instead: the likelihood this is 13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * desired is very low! 13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_sign(intn) == -1 && dv->type == DV_ULEB128) 13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("negative value in unsigned LEB128")); 13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (dv->multiple) { 14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value val; 14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_value_finalize_expr(&val, dv->multiple, prev_bc, 0)) 14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TOO_COMPLEX, 14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("multiple expression too complex")); 14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (val.rel) 14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_NOT_ABSOLUTE, 14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("multiple expression not absolute")); 15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dv->multiple = val.abs; 15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbc_data_item_size(yasm_bytecode *bc) 15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bytecode_data *bc_data = (bytecode_data *)bc->contents; 15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return bc_data->item_size; 16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbc_data_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, 16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org void *add_span_data) 16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bytecode_data *bc_data = (bytecode_data *)bc->contents; 16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dataval *dv; 16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *intn; 16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long len = 0; 17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long multiple; 17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Count up element sizes, rounding up string length. */ 17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_FOREACH(dv, &bc_data->datahead, link) { 17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (dv->type) { 17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_EMPTY: 17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = 0; 17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_VALUE: 17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = dv->data.val.size/8; 18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_RAW: 18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = dv->data.raw.len; 18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_ULEB128: 18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_SLEB128: 18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_expr_get_intnum(&dv->data.val.abs, 0); 18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!intn) 18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_internal_error(N_("non-constant in data_tobytes")); 18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = yasm_intnum_size_leb128(intn, dv->type == DV_SLEB128); 19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_RESERVE: 19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = dv->data.val.size/8; 19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!yasm_dv_get_multiple(dv, &multiple)) 19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len *= multiple; 19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc->len += len; 20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 206d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orgbc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, 207d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org unsigned char *bufstart, void *d, 20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_output_value_func output_value, 20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@unused@*/ yasm_output_reloc_func output_reloc) 21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bytecode_data *bc_data = (bytecode_data *)bc->contents; 21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dataval *dv; 21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *intn; 21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int val_len; 21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long multiple, i; 21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_FOREACH(dv, &bc_data->datahead, link) { 21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_dv_get_multiple(dv, &multiple) || multiple == 0) 21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (dv->type) { 22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_EMPTY: 22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_VALUE: 22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org val_len = dv->data.val.size/8; 22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<multiple; i++) { 22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (output_value(&dv->data.val, *bufp, val_len, 227d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org (unsigned long)(*bufp-bufstart), bc, 1, 22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org d)) 22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *bufp += val_len; 23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_RAW: 23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<multiple; i++) { 23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memcpy(*bufp, dv->data.raw.contents, dv->data.raw.len); 23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *bufp += dv->data.raw.len; 23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_ULEB128: 24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_SLEB128: 24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_expr_get_intnum(&dv->data.val.abs, 234); 24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!intn) 24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_internal_error(N_("non-constant in data_tobytes")); 24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<multiple; i++) { 24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *bufp += 24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_get_leb128(intn, *bufp, 24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dv->type == DV_SLEB128); 24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_RESERVE: 25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org val_len = dv->data.val.size/8; 25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<multiple; i++) { 25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memset(*bufp, 0, val_len); 25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *bufp += val_len; 25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_bytecode * 26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_bc_create_data(yasm_datavalhead *datahead, unsigned int size, 26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int append_zero, yasm_arch *arch, unsigned long line) 26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bytecode_data *data = yasm_xmalloc(sizeof(bytecode_data)); 26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bytecode *bc = yasm_bc_create_common(&bc_data_callback, data, line); 26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dataval *dv, *dv2, *dvo; 26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *intn; 27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long len = 0, rlen, i; 27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dvs_initialize(&data->datahead); 27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->item_size = size; 27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Prescan input data for length, etc. Careful: this needs to be 27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * precisely paired with the second loop. 27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_FOREACH(dv, datahead, link) { 28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (dv->multiple && dv->type != DV_EMPTY && len > 0) { 28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Flush previous data */ 28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo = yasm_dv_create_raw(yasm_xmalloc(len), len); 28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_INSERT_TAIL(&data->datahead, dvo, link); 28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = 0; 28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (dv->type) { 28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_EMPTY: 28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_VALUE: 29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_ULEB128: 29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_SLEB128: 29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_expr_get_intnum(&dv->data.val.abs, 0); 29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (intn && dv->type == DV_VALUE && (arch || size == 1)) 29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += size; 29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (intn && dv->type == DV_ULEB128) 29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += yasm_intnum_size_leb128(intn, 0); 29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (intn && dv->type == DV_SLEB128) 29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += yasm_intnum_size_leb128(intn, 1); 29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else { 30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (len > 0) { 30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Create bytecode for all previous len */ 30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo = yasm_dv_create_raw(yasm_xmalloc(len), len); 30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_INSERT_TAIL(&data->datahead, dvo, link); 30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = 0; 30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Create bytecode for this value */ 30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo = yasm_xmalloc(sizeof(yasm_dataval)); 30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_INSERT_TAIL(&data->datahead, dvo, link); 31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo->multiple = dv->multiple; 31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_RAW: 31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org rlen = dv->data.raw.len; 31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* find count, rounding up to nearest multiple of size */ 31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org rlen = (rlen + size - 1) / size; 31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += rlen*size; 31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_RESERVE: 32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += size; 32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (dv->multiple && dv->type != DV_EMPTY && len > 0) { 32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Flush this data */ 32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo = yasm_dv_create_raw(yasm_xmalloc(len), len); 32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_INSERT_TAIL(&data->datahead, dvo, link); 32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo->multiple = dv->multiple; 32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = 0; 33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (append_zero) 33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len++; 33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Create final dataval for any trailing length */ 33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (len > 0) { 33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo = yasm_dv_create_raw(yasm_xmalloc(len), len); 33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_INSERT_TAIL(&data->datahead, dvo, link); 34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Second iteration: copy data and delete input datavals. */ 34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dv = STAILQ_FIRST(datahead); 34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo = STAILQ_FIRST(&data->datahead); 34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = 0; 34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (dv && dvo) { 34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (dv->multiple && dv->type != DV_EMPTY && len > 0) { 34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo = STAILQ_NEXT(dvo, link); 34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = 0; 35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (dv->type) { 35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_EMPTY: 35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_VALUE: 35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_ULEB128: 35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_SLEB128: 35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_expr_get_intnum(&dv->data.val.abs, 0); 35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (intn && dv->type == DV_VALUE && (arch || size == 1)) { 35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (size == 1) 36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_get_sized(intn, 36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org &dvo->data.raw.contents[len], 36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1, 8, 0, 0, 1); 36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_arch_intnum_tobytes(arch, intn, 36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org &dvo->data.raw.contents[len], 36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size, size*8, 0, bc, 1); 36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value_delete(&dv->data.val); 36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += size; 36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (intn && dv->type == DV_ULEB128) { 37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += yasm_intnum_get_leb128(intn, 37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org &dvo->data.raw.contents[len], 37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 0); 37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value_delete(&dv->data.val); 37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (intn && dv->type == DV_SLEB128) { 37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += yasm_intnum_get_leb128(intn, 37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org &dvo->data.raw.contents[len], 37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1); 37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value_delete(&dv->data.val); 37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (len > 0) 38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo = STAILQ_NEXT(dvo, link); 38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo->type = dv->type; 38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo->data.val = dv->data.val; /* structure copy */ 38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo->data.val.size = size*8; /* remember size */ 38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo = STAILQ_NEXT(dvo, link); 38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = 0; 38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_RAW: 39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org rlen = dv->data.raw.len; 39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memcpy(&dvo->data.raw.contents[len], dv->data.raw.contents, 39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org rlen); 39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(dv->data.raw.contents); 39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += rlen; 39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* pad with 0's to nearest multiple of size */ 39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org rlen %= size; 39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (rlen > 0) { 39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org rlen = size-rlen; 39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<rlen; i++) 40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo->data.raw.contents[len++] = 0; 40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_RESERVE: 40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memset(&dvo->data.raw.contents[len], 0, size); 40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += size; 40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 40745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 40845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (dv->multiple && dv->type != DV_EMPTY && len > 0) { 41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo = STAILQ_NEXT(dvo, link); 41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = 0; 41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (append_zero) 41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dvo->data.raw.contents[len++] = 0; 41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dv2 = STAILQ_NEXT(dv, link); 41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(dv); 41845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dv = dv2; 41945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 42045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 42145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return bc; 42245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 42345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 42445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_bytecode * 42545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_bc_create_leb128(yasm_datavalhead *datahead, int sign, unsigned long line) 42645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 42745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dataval *dv; 42845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 42945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Convert all values into LEB type, error on strings/raws */ 43045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_FOREACH(dv, datahead, link) { 43145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (dv->type) { 43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_VALUE: 43345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dv->type = sign ? DV_SLEB128 : DV_ULEB128; 43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_RAW: 43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("LEB128 does not allow string constants")); 43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 44245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 44345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return yasm_bc_create_data(datahead, 0, 0, 0, line); 44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dataval * 44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dv_create_expr(yasm_expr *e) 44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval)); 45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval->type = DV_VALUE; 45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value_initialize(&retval->data.val, e, 0); 45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval->multiple = NULL; 45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return retval; 45745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 45845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 45945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dataval * 46045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dv_create_raw(unsigned char *contents, unsigned long len) 46145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 46245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval)); 46345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 46445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval->type = DV_RAW; 46545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval->data.raw.contents = contents; 46645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval->data.raw.len = len; 46745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval->multiple = NULL; 46845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 46945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return retval; 47045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 47145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 47245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dataval * 47345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dv_create_reserve(void) 47445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 47545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval)); 47645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 47745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval->type = DV_RESERVE; 47845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval->multiple = NULL; 47945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 48045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return retval; 48145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 48245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 483d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orgyasm_value * 484d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orgyasm_dv_get_value(yasm_dataval *dv) 485d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org{ 486d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org if (dv->type != DV_VALUE) 487d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org return NULL; 488d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org return &dv->data.val; 489d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org} 490d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org 49145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 49245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dv_set_multiple(yasm_dataval *dv, yasm_expr *e) 49345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 49445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (dv->multiple) 49545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dv->multiple = yasm_expr_create_tree( dv->multiple, YASM_EXPR_MUL, e, 49645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org e->line); 49745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 49845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dv->multiple = e; 49945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 50045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 50145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint 50245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dv_get_multiple(yasm_dataval *dv, unsigned long *multiple) 50345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 50445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ /*@null@*/ const yasm_intnum *num; 50545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 50645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *multiple = 1; 50745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (dv->multiple) { 50845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org num = yasm_expr_get_intnum(&dv->multiple, 0); 50945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!num) { 51045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 51145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("could not determine multiple")); 51245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 51345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 51445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_sign(num) < 0) { 51545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, N_("multiple is negative")); 51645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 51745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 51845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *multiple = yasm_intnum_get_uint(num); 51945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 52045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 52145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 52245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 52345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 52445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dvs_delete(yasm_datavalhead *headp) 52545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 52645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dataval *cur, *next; 52745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 52845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cur = STAILQ_FIRST(headp); 52945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (cur) { 53045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org next = STAILQ_NEXT(cur, link); 53145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (cur->type) { 53245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_VALUE: 53345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value_delete(&cur->data.val); 53445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 53545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_RAW: 53645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(cur->data.raw.contents); 53745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 53845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 53945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 54045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 54145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (cur->multiple) 54245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(cur->multiple); 54345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(cur); 54445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cur = next; 54545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 54645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_INIT(headp); 54745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 54845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 54945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dataval * 55045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dvs_append(yasm_datavalhead *headp, yasm_dataval *dv) 55145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 55245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (dv) { 55345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_INSERT_TAIL(headp, dv, link); 55445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return dv; 55545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 55645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (yasm_dataval *)NULL; 55745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 55845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 55945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 56045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dvs_print(const yasm_datavalhead *head, FILE *f, int indent_level) 56145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 56245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dataval *cur; 56345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long i; 56445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 56545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_FOREACH(cur, head, link) { 56645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*sMultiple=", indent_level, ""); 56745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!cur->multiple) 56845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "nil (1)"); 56945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 57045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_print(cur->multiple, f); 57145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (cur->type) { 57245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_EMPTY: 57345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*sEmpty\n", indent_level, ""); 57445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 57545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_VALUE: 57645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*sValue:\n", indent_level, ""); 57745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value_print(&cur->data.val, f, indent_level+1); 57845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 57945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_RAW: 58045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*sLength=%lu\n", indent_level, "", 58145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cur->data.raw.len); 58245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*sBytes=[", indent_level, ""); 58345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<cur->data.raw.len; i++) 58445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "0x%02x, ", cur->data.raw.contents[i]); 58545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "]\n"); 58645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 58745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_ULEB128: 58845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*sULEB128 value:\n", indent_level, ""); 58945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value_print(&cur->data.val, f, indent_level+1); 59045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 59145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_SLEB128: 59245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*sSLEB128 value:\n", indent_level, ""); 59345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value_print(&cur->data.val, f, indent_level+1); 59445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 59545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case DV_RESERVE: 59645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*sReserved\n", indent_level, ""); 59745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 59845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 59945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 60045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 601