• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Bytecode utility functions
3  *
4  *  Copyright (C) 2001-2007  Peter Johnson
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 #include "util.h"
28 
29 #include "libyasm-stdint.h"
30 #include "coretype.h"
31 
32 #include "errwarn.h"
33 #include "intnum.h"
34 #include "expr.h"
35 #include "value.h"
36 
37 #include "bytecode.h"
38 
39 
40 typedef struct bytecode_reserve {
41     /*@only@*/ /*@null@*/ yasm_expr *numitems; /* number of items to reserve */
42     unsigned int itemsize;          /* size of each item (in bytes) */
43 } bytecode_reserve;
44 
45 static void bc_reserve_destroy(void *contents);
46 static void bc_reserve_print(const void *contents, FILE *f, int indent_level);
47 static void bc_reserve_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
48 static int bc_reserve_elem_size(yasm_bytecode *bc);
49 static int bc_reserve_calc_len(yasm_bytecode *bc,
50                                yasm_bc_add_span_func add_span,
51                                void *add_span_data);
52 static int bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp,
53                               unsigned char *bufstart, void *d,
54                               yasm_output_value_func output_value,
55                               /*@null@*/ yasm_output_reloc_func output_reloc);
56 
57 static const yasm_bytecode_callback bc_reserve_callback = {
58     bc_reserve_destroy,
59     bc_reserve_print,
60     bc_reserve_finalize,
61     bc_reserve_elem_size,
62     bc_reserve_calc_len,
63     yasm_bc_expand_common,
64     bc_reserve_tobytes,
65     YASM_BC_SPECIAL_RESERVE
66 };
67 
68 
69 static void
bc_reserve_destroy(void * contents)70 bc_reserve_destroy(void *contents)
71 {
72     bytecode_reserve *reserve = (bytecode_reserve *)contents;
73     yasm_expr_destroy(reserve->numitems);
74     yasm_xfree(contents);
75 }
76 
77 static void
bc_reserve_print(const void * contents,FILE * f,int indent_level)78 bc_reserve_print(const void *contents, FILE *f, int indent_level)
79 {
80     const bytecode_reserve *reserve = (const bytecode_reserve *)contents;
81     fprintf(f, "%*s_Reserve_\n", indent_level, "");
82     fprintf(f, "%*sNum Items=", indent_level, "");
83     yasm_expr_print(reserve->numitems, f);
84     fprintf(f, "\n%*sItem Size=%u\n", indent_level, "", reserve->itemsize);
85 }
86 
87 static void
bc_reserve_finalize(yasm_bytecode * bc,yasm_bytecode * prev_bc)88 bc_reserve_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
89 {
90     bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
91     /* multiply reserve expression into multiple */
92     if (!bc->multiple)
93         bc->multiple = reserve->numitems;
94     else
95         bc->multiple = yasm_expr_create_tree(bc->multiple, YASM_EXPR_MUL,
96                                              reserve->numitems, bc->line);
97     reserve->numitems = NULL;
98 }
99 
100 static int
bc_reserve_elem_size(yasm_bytecode * bc)101 bc_reserve_elem_size(yasm_bytecode *bc)
102 {
103     bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
104     return reserve->itemsize;
105 }
106 
107 static int
bc_reserve_calc_len(yasm_bytecode * bc,yasm_bc_add_span_func add_span,void * add_span_data)108 bc_reserve_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
109                     void *add_span_data)
110 {
111     bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
112     bc->len += reserve->itemsize;
113     return 0;
114 }
115 
116 static int
bc_reserve_tobytes(yasm_bytecode * bc,unsigned char ** bufp,unsigned char * bufstart,void * d,yasm_output_value_func output_value,yasm_output_reloc_func output_reloc)117 bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp,
118                    unsigned char *bufstart, void *d,
119                    yasm_output_value_func output_value,
120                    /*@unused@*/ yasm_output_reloc_func output_reloc)
121 {
122     yasm_internal_error(N_("bc_reserve_tobytes called"));
123     /*@notreached@*/
124     return 1;
125 }
126 
127 yasm_bytecode *
yasm_bc_create_reserve(yasm_expr * numitems,unsigned int itemsize,unsigned long line)128 yasm_bc_create_reserve(yasm_expr *numitems, unsigned int itemsize,
129                        unsigned long line)
130 {
131     bytecode_reserve *reserve = yasm_xmalloc(sizeof(bytecode_reserve));
132 
133     /*@-mustfree@*/
134     reserve->numitems = numitems;
135     /*@=mustfree@*/
136     reserve->itemsize = itemsize;
137 
138     return yasm_bc_create_common(&bc_reserve_callback, reserve, line);
139 }
140 
141 const yasm_expr *
yasm_bc_reserve_numitems(yasm_bytecode * bc,unsigned int * itemsize)142 yasm_bc_reserve_numitems(yasm_bytecode *bc, unsigned int *itemsize)
143 {
144     bytecode_reserve *reserve;
145 
146     if (bc->callback != &bc_reserve_callback)
147         return NULL;
148 
149     reserve = (bytecode_reserve *)bc->contents;
150     *itemsize = reserve->itemsize;
151     return reserve->numitems;
152 }
153