annotate lwasm/section.c @ 385:cf8c92d70eb1

Various bugfixes
author lost@starbug
date Sun, 16 May 2010 11:50:00 -0600
parents cc154dc614fe
children a741d2e4869f
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);
367
34dfc9747f23 Reduction passes complete
lost@starbug
parents: 363
diff changeset
90 s -> offset = lw_expr_build(lw_expr_type_special, lwasm_expr_secbase, s);
353
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)
385
cf8c92d70eb1 Various bugfixes
lost@starbug
parents: 380
diff changeset
176 {
356
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
177 sym = lw_strdup(l -> sym);
385
cf8c92d70eb1 Various bugfixes
lost@starbug
parents: 380
diff changeset
178 l -> symset = 1;
cf8c92d70eb1 Various bugfixes
lost@starbug
parents: 380
diff changeset
179 }
356
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
180
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
181 if (l -> sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
182 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
183 skip_operand(p);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
184 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
185
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
186 again:
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
187 if (after || !sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
188 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
189 char *p2;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
190
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
191 after = 1;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
192 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
193 /* do nothing */ ;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
194
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
195 sym = lw_strndup(*p, p2 - *p);
385
cf8c92d70eb1 Various bugfixes
lost@starbug
parents: 380
diff changeset
196 *p = p2;
356
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
197 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
198 if (!sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
199 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
200 lwasm_register_error(as, l, "No symbol for EXPORT");
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
201 return;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
202 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
203
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
204 // add the symbol to the "export" list (which will be resolved
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
205 // after the parse pass is complete
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
206 e = lw_alloc(sizeof(exportlist_t));
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
207 e -> next = as -> exportlist;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
208 e -> symbol = lw_strdup(sym);
363
d96c30e60ddf Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents: 356
diff changeset
209 e -> line = l;
374
d99322ef6f21 Stage 1: actually do output
lost@starbug
parents: 367
diff changeset
210 e -> se = NULL;
356
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
211 as -> exportlist = e;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
212 lw_free(sym);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
213
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
214 if (after && **p == ',')
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
215 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
216 (*p)++;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
217 for (; **p && isspace(**p); (*p)++)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
218 /* do nothing */ ;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
219 goto again;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
220 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
221 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
222
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
223 PARSEFUNC(pseudo_parse_extern)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
224 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
225 int after = 0;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
226 char *sym = NULL;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
227 importlist_t *e;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
228
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
229 if (as -> output_format != OUTPUT_OBJ)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
230 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
231 lwasm_register_error(as, l, "IMPORT only supported for object target");
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
232 return;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
233 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
234
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
235 if (l -> sym)
385
cf8c92d70eb1 Various bugfixes
lost@starbug
parents: 380
diff changeset
236 {
356
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
237 sym = lw_strdup(l -> sym);
385
cf8c92d70eb1 Various bugfixes
lost@starbug
parents: 380
diff changeset
238 l -> symset = 1;
cf8c92d70eb1 Various bugfixes
lost@starbug
parents: 380
diff changeset
239 }
356
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
240
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
241 if (l -> sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
242 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
243 skip_operand(p);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
244 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
245
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
246 again:
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
247 if (after || !sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
248 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
249 char *p2;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
250
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
251 after = 1;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
252 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
253 /* do nothing */ ;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
254
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
255 sym = lw_strndup(*p, p2 - *p);
385
cf8c92d70eb1 Various bugfixes
lost@starbug
parents: 380
diff changeset
256 *p = p2;
356
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
257 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
258 if (!sym)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
259 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
260 lwasm_register_error(as, l, "No symbol for IMPORT");
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
261 return;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
262 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
263
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
264 // add the symbol to the "export" list (which will be resolved
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
265 // after the parse pass is complete
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
266 e = lw_alloc(sizeof(importlist_t));
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
267 e -> next = as -> importlist;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
268 e -> symbol = lw_strdup(sym);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
269 as -> importlist = e;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
270 lw_free(sym);
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
271
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
272 if (after && **p == ',')
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
273 {
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
274 (*p)++;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
275 for (; **p && isspace(**p); (*p)++)
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
276 /* do nothing */ ;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
277 goto again;
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
278 }
7166254491ed Finished pseudo ops
lost@starbug
parents: 353
diff changeset
279 }
380
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
280
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
281 PARSEFUNC(pseudo_parse_extdep)
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
282 {
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
283 int after = 0;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
284 char *sym = NULL;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
285 importlist_t *e;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
286
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
287 if (as -> output_format != OUTPUT_OBJ)
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
288 {
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
289 lwasm_register_error(as, l, "EXTDEP only supported for object target");
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
290 return;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
291 }
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
292
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
293 if (!as -> csect)
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
294 {
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
295 lwasm_register_error(as, l, "EXTDEP must be within a section");
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
296 return;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
297 }
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
298
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
299 if (l -> sym)
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
300 sym = lw_strdup(l -> sym);
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
301
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
302 if (l -> sym)
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
303 {
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
304 skip_operand(p);
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
305 }
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
306
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
307 again:
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
308 if (after || !sym)
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
309 {
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
310 char *p2;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
311
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
312 after = 1;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
313 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++)
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
314 /* do nothing */ ;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
315
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
316 sym = lw_strndup(*p, p2 - *p);
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
317 }
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
318 if (!sym)
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
319 {
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
320 lwasm_register_error(as, l, "No symbol for EXTDEP");
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
321 return;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
322 }
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
323
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
324 // create a zero-width dependency
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
325 {
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
326 lw_expr_t e;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
327 e = lw_expr_build(lw_expr_type_int, 0);
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
328 lwasm_emitexpr(l, e, 0);
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
329 lw_expr_destroy(e);
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
330 }
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
331
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
332 if (after && **p == ',')
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
333 {
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
334 (*p)++;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
335 for (; **p && isspace(**p); (*p)++)
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
336 /* do nothing */ ;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
337 goto again;
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
338 }
cc154dc614fe Added extdep pseudo back in
lost@starbug
parents: 374
diff changeset
339 }