annotate lwasm/section.c @ 356:7166254491ed

Finished pseudo ops
author lost@starbug
date Wed, 31 Mar 2010 18:46:32 -0600
parents faa97115952e
children d96c30e60ddf
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
353
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
1 /*
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
2 section.c
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
3
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
4 Copyright © 2010 William Astle
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
5
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
6 This file is part of LWTOOLS.
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
7
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
8 LWTOOLS is free software: you can redistribute it and/or modify it under the
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
9 terms of the GNU General Public License as published by the Free Software
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
10 Foundation, either version 3 of the License, or (at your option) any later
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
11 version.
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
12
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
13 This program is distributed in the hope that it will be useful, but WITHOUT
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
16 more details.
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
17
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
18 You should have received a copy of the GNU General Public License along with
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
19 this program. If not, see <http://www.gnu.org/licenses/>.
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
20 */
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
21
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
22 #include <config.h>
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
23
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
24 #include <string.h>
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
25
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
26 #include <lw_string.h>
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
27 #include <lw_alloc.h>
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
28
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
29 #include "lwasm.h"
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
30 #include "instab.h"
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
31
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
32 PARSEFUNC(pseudo_parse_section)
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
33 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
34 char *p2;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
35 char *sn;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
36 char *opts = NULL;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
37 sectiontab_t *s;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
38
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
39 if (as -> output_format != OUTPUT_OBJ)
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
40 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
41 lwasm_register_error(as, l, "Cannot use sections unless using the object target");
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
42 return;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
43 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
44
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
45 if (!**p)
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
46 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
47 lwasm_register_error(as, l, "Need section name");
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
48 return;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
49 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
50
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
51 if (as -> csect)
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
52 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
53 lw_expr_destroy(as -> csect -> offset);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
54 as -> csect -> offset = l -> addr;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
55 as -> csect = NULL;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
56 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
57
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
58 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++)
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
59 /* do nothing */ ;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
60
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
61 sn = lw_strndup(*p, p2 - *p);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
62 *p = p2;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
63
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
64 if (**p == ',')
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
65 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
66 // have opts
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
67 (*p)++;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
68
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
69 for (p2 = *p; *p2 && !isspace(*p2); p2++)
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
70 /* do nothing */ ;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
71
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
72 opts = lw_strndup(*p, p2 - *p);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
73 *p = p2;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
74 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
75
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
76 for (s = as -> sections; s; s = s -> next)
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
77 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
78 if (!strcmp(s -> name, sn))
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
79 break;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
80 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
81 if (s && opts)
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
82 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
83 lwasm_register_warning(as, l, "Section flags can only be specified the first time; ignoring duplicate definition");
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
84 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
85 if (!s)
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
86 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
87 // create section data structure
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
88 s = lw_alloc(sizeof(sectiontab_t));
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
89 s -> name = lw_strdup(sn);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
90 s -> offset = lw_expr_build(lw_expr_type_int, 0);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
91 s -> flags = section_flag_none;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
92 if (!strcasecmp(sn, "bss") || !strcasecmp(sn, ".bss"))
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
93 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
94 s -> flags |= section_flag_bss;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
95 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
96 // parse options
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
97 if (opts)
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
98 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
99 // only one option ("bss" or "!bss")
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
100 if (!strcasecmp(opts, "bss"))
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
101 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
102 s -> flags |= section_flag_bss;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
103 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
104 else if (!strcasecmp(opts, "!bss"))
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
105 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
106 s -> flags &= ~section_flag_bss;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
107 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
108 else
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
109 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
110 lwasm_register_error(as, l, "Unrecognized section flag");
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
111 lw_free(sn);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
112 lw_free(opts);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
113 lw_free(s -> name);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
114 lw_expr_destroy(s -> offset);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
115 lw_free(s);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
116 return;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
117 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
118 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
119 s -> next = as -> sections;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
120 as -> sections = s;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
121 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
122
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
123 lw_expr_destroy(l -> addr);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
124 l -> addr = lw_expr_copy(s -> offset);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
125
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
126 as -> csect = s;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
127 as -> context = lwasm_next_context(as);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
128
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
129 l -> len = 0;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
130
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
131 lw_free(opts);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
132 lw_free(sn);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
133 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
134
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
135 PARSEFUNC(pseudo_parse_endsection)
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
136 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
137 if (as -> output_format != OUTPUT_OBJ)
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
138 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
139 lwasm_register_error(as, l, "Cannot use sections unless using the object target");
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
140 return;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
141 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
142
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
143 if (!(as -> csect))
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
144 {
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
145 lwasm_register_error(as, l, "ENDSECTION without SECTION");
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
146 return;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
147 }
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
148
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
149 // save offset in case another instance of the section appears
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
150 lw_expr_destroy(as -> csect -> offset);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
151 as -> csect -> offset = l -> addr;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
152
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
153 // reset address to 0
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
154 l -> addr = lw_expr_build(lw_expr_type_int, 0);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
155 as -> csect = NULL;
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
156
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
157 // end of section is a context break
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
158 as -> context = lwasm_next_context(as);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
159
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
160 skip_operand(p);
faa97115952e Added SECTION/ENDSECTION
lost@starbug
parents:
diff changeset
161 }
356
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
162
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
163 PARSEFUNC(pseudo_parse_export)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
164 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
165 int after = 0;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
166 char *sym = NULL;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
167 exportlist_t *e;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
168
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
169 if (as -> output_format != OUTPUT_OBJ)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
170 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
171 lwasm_register_error(as, l, "EXPORT only supported for object target");
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
172 return;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
173 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
174
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
175 if (l -> sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
176 sym = lw_strdup(l -> sym);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
177
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
178 if (l -> sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
179 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
180 skip_operand(p);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
181 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
182
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
183 again:
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
184 if (after || !sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
185 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
186 char *p2;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
187
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
188 after = 1;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
189 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
190 /* do nothing */ ;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
191
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
192 sym = lw_strndup(*p, p2 - *p);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
193 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
194 if (!sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
195 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
196 lwasm_register_error(as, l, "No symbol for EXPORT");
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
197 return;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
198 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
199
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
200 // add the symbol to the "export" list (which will be resolved
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
201 // after the parse pass is complete
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
202 e = lw_alloc(sizeof(exportlist_t));
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
203 e -> next = as -> exportlist;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
204 e -> symbol = lw_strdup(sym);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
205 as -> exportlist = e;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
206 lw_free(sym);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
207
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
208 if (after && **p == ',')
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
209 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
210 (*p)++;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
211 for (; **p && isspace(**p); (*p)++)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
212 /* do nothing */ ;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
213 goto again;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
214 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
215 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
216
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
217 PARSEFUNC(pseudo_parse_extern)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
218 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
219 int after = 0;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
220 char *sym = NULL;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
221 importlist_t *e;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
222
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
223 if (as -> output_format != OUTPUT_OBJ)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
224 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
225 lwasm_register_error(as, l, "IMPORT only supported for object target");
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
226 return;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
227 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
228
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
229 if (l -> sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
230 sym = lw_strdup(l -> sym);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
231
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
232 if (l -> sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
233 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
234 skip_operand(p);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
235 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
236
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
237 again:
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
238 if (after || !sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
239 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
240 char *p2;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
241
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
242 after = 1;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
243 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
244 /* do nothing */ ;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
245
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
246 sym = lw_strndup(*p, p2 - *p);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
247 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
248 if (!sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
249 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
250 lwasm_register_error(as, l, "No symbol for IMPORT");
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
251 return;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
252 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
253
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
254 // add the symbol to the "export" list (which will be resolved
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
255 // after the parse pass is complete
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
256 e = lw_alloc(sizeof(importlist_t));
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
257 e -> next = as -> importlist;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
258 e -> symbol = lw_strdup(sym);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
259 as -> importlist = e;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
260 lw_free(sym);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
261
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
262 if (after && **p == ',')
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
263 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
264 (*p)++;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
265 for (; **p && isspace(**p); (*p)++)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
266 /* do nothing */ ;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
267 goto again;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
268 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
269 }