comparison lwasm/section.c @ 353:faa97115952e

Added SECTION/ENDSECTION
author lost@starbug
date Tue, 30 Mar 2010 21:48:49 -0600
parents
children 7166254491ed
comparison
equal deleted inserted replaced
352:f5b77989f675 353:faa97115952e
1 /*
2 section.c
3
4 Copyright © 2010 William Astle
5
6 This file is part of LWTOOLS.
7
8 LWTOOLS is free software: you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation, either version 3 of the License, or (at your option) any later
11 version.
12
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 more details.
17
18 You should have received a copy of the GNU General Public License along with
19 this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <config.h>
23
24 #include <string.h>
25
26 #include <lw_string.h>
27 #include <lw_alloc.h>
28
29 #include "lwasm.h"
30 #include "instab.h"
31
32 PARSEFUNC(pseudo_parse_section)
33 {
34 char *p2;
35 char *sn;
36 char *opts = NULL;
37 sectiontab_t *s;
38
39 if (as -> output_format != OUTPUT_OBJ)
40 {
41 lwasm_register_error(as, l, "Cannot use sections unless using the object target");
42 return;
43 }
44
45 if (!**p)
46 {
47 lwasm_register_error(as, l, "Need section name");
48 return;
49 }
50
51 if (as -> csect)
52 {
53 lw_expr_destroy(as -> csect -> offset);
54 as -> csect -> offset = l -> addr;
55 as -> csect = NULL;
56 }
57
58 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++)
59 /* do nothing */ ;
60
61 sn = lw_strndup(*p, p2 - *p);
62 *p = p2;
63
64 if (**p == ',')
65 {
66 // have opts
67 (*p)++;
68
69 for (p2 = *p; *p2 && !isspace(*p2); p2++)
70 /* do nothing */ ;
71
72 opts = lw_strndup(*p, p2 - *p);
73 *p = p2;
74 }
75
76 for (s = as -> sections; s; s = s -> next)
77 {
78 if (!strcmp(s -> name, sn))
79 break;
80 }
81 if (s && opts)
82 {
83 lwasm_register_warning(as, l, "Section flags can only be specified the first time; ignoring duplicate definition");
84 }
85 if (!s)
86 {
87 // create section data structure
88 s = lw_alloc(sizeof(sectiontab_t));
89 s -> name = lw_strdup(sn);
90 s -> offset = lw_expr_build(lw_expr_type_int, 0);
91 s -> flags = section_flag_none;
92 if (!strcasecmp(sn, "bss") || !strcasecmp(sn, ".bss"))
93 {
94 s -> flags |= section_flag_bss;
95 }
96 // parse options
97 if (opts)
98 {
99 // only one option ("bss" or "!bss")
100 if (!strcasecmp(opts, "bss"))
101 {
102 s -> flags |= section_flag_bss;
103 }
104 else if (!strcasecmp(opts, "!bss"))
105 {
106 s -> flags &= ~section_flag_bss;
107 }
108 else
109 {
110 lwasm_register_error(as, l, "Unrecognized section flag");
111 lw_free(sn);
112 lw_free(opts);
113 lw_free(s -> name);
114 lw_expr_destroy(s -> offset);
115 lw_free(s);
116 return;
117 }
118 }
119 s -> next = as -> sections;
120 as -> sections = s;
121 }
122
123 lw_expr_destroy(l -> addr);
124 l -> addr = lw_expr_copy(s -> offset);
125
126 as -> csect = s;
127 as -> context = lwasm_next_context(as);
128
129 l -> len = 0;
130
131 lw_free(opts);
132 lw_free(sn);
133 }
134
135 PARSEFUNC(pseudo_parse_endsection)
136 {
137 if (as -> output_format != OUTPUT_OBJ)
138 {
139 lwasm_register_error(as, l, "Cannot use sections unless using the object target");
140 return;
141 }
142
143 if (!(as -> csect))
144 {
145 lwasm_register_error(as, l, "ENDSECTION without SECTION");
146 return;
147 }
148
149 // save offset in case another instance of the section appears
150 lw_expr_destroy(as -> csect -> offset);
151 as -> csect -> offset = l -> addr;
152
153 // reset address to 0
154 l -> addr = lw_expr_build(lw_expr_type_int, 0);
155 as -> csect = NULL;
156
157 // end of section is a context break
158 as -> context = lwasm_next_context(as);
159
160 skip_operand(p);
161 }