1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "dtc.h"
22
23void fixup_free(struct fixup *f)
24{
25 free(f->ref);
26 free(f);
27}
28
29void data_free(struct data d)
30{
31 struct fixup *f;
32
33 f = d.refs;
34 while (f) {
35 struct fixup *nf;
36
37 nf = f->next;
38 fixup_free(f);
39 f = nf;
40 }
41
42 assert(!d.val || d.asize);
43
44 if (d.val)
45 free(d.val);
46}
47
48struct data data_grow_for(struct data d, int xlen)
49{
50 struct data nd;
51 int newsize;
52
53
54 assert(!d.val || d.asize);
55
56 if (xlen == 0)
57 return d;
58
59 newsize = xlen;
60
61 while ((d.len + xlen) > newsize)
62 newsize *= 2;
63
64 nd.asize = newsize;
65 nd.val = xrealloc(d.val, newsize);
66 nd.len = d.len;
67 nd.type = d.type;
68 nd.refs = d.refs;
69
70 assert(nd.asize >= (d.len + xlen));
71
72 return nd;
73}
74
75struct data data_copy_mem(char *mem, int len)
76{
77 struct data d;
78
79 d = data_grow_for(empty_data, len);
80
81 d.len = len;
82 memcpy(d.val, mem, len);
83
84 return d;
85}
86
87static char get_oct_char(char *s, int *i)
88{
89 char x[4];
90 char *endx;
91 long val;
92
93 x[3] = '\0';
94 x[0] = s[(*i)];
95 if (x[0]) {
96 x[1] = s[(*i)+1];
97 if (x[1])
98 x[2] = s[(*i)+2];
99 }
100
101 val = strtol(x, &endx, 8);
102 if ((endx - x) == 0)
103 fprintf(stderr, "Empty \\nnn escape\n");
104
105 (*i) += endx - x;
106 return val;
107}
108
109static char get_hex_char(char *s, int *i)
110{
111 char x[3];
112 char *endx;
113 long val;
114
115 x[2] = '\0';
116 x[0] = s[(*i)];
117 if (x[0])
118 x[1] = s[(*i)+1];
119
120 val = strtol(x, &endx, 16);
121 if ((endx - x) == 0)
122 fprintf(stderr, "Empty \\x escape\n");
123
124 (*i) += endx - x;
125 return val;
126}
127
128struct data data_copy_escape_string(char *s, int len)
129{
130 int i = 0;
131 struct data d;
132 unsigned char *q;
133
134 d = data_grow_for(empty_data, strlen(s)+1);
135
136 q = d.val;
137 while (i < len) {
138 char c = s[i++];
139
140 if (c != '\\') {
141 q[d.len++] = c;
142 continue;
143 }
144
145 c = s[i++];
146 assert(c);
147 switch (c) {
148 case 't':
149 q[d.len++] = '\t';
150 break;
151 case 'n':
152 q[d.len++] = '\n';
153 break;
154 case 'r':
155 q[d.len++] = '\r';
156 break;
157 case '0':
158 case '1':
159 case '2':
160 case '3':
161 case '4':
162 case '5':
163 case '6':
164 case '7':
165 i--;
166
167 q[d.len++] = get_oct_char(s, &i);
168 break;
169 case 'x':
170 q[d.len++] = get_hex_char(s, &i);
171 break;
172 default:
173 q[d.len++] = c;
174 }
175 }
176
177 q[d.len++] = '\0';
178 return d;
179}
180
181struct data data_copy_file(FILE *f, size_t len)
182{
183 struct data d;
184
185 d = data_grow_for(empty_data, len);
186
187 d.len = len;
188 fread(d.val, len, 1, f);
189
190 return d;
191}
192
193struct data data_append_data(struct data d, void *p, int len)
194{
195 d = data_grow_for(d, len);
196 memcpy(d.val + d.len, p, len);
197 d.len += len;
198 return d;
199}
200
201struct data data_append_cell(struct data d, cell_t word)
202{
203
204
205 cell_t beword = word;
206
207 d.type = 'C';
208
209 return data_append_data(d, &beword, sizeof(beword));
210}
211
212struct data data_append_re(struct data d, struct reserve_entry *re)
213{
214 struct reserve_entry bere;
215
216 bere.address = cpu_to_be64(re->address);
217 bere.size = cpu_to_be64(re->size);
218
219 return data_append_data(d, &bere, sizeof(bere));
220}
221
222struct data data_append_addr(struct data d, u64 addr)
223{
224 u64 beaddr = cpu_to_be64(addr);
225
226 return data_append_data(d, &beaddr, sizeof(beaddr));
227}
228
229struct data data_append_byte(struct data d, uint8_t byte)
230{
231
232 d.type = 'B';
233 return data_append_data(d, &byte, 1);
234}
235
236struct data data_append_zeroes(struct data d, int len)
237{
238 d = data_grow_for(d, len);
239
240 memset(d.val + d.len, 0, len);
241 d.len += len;
242 return d;
243}
244
245struct data data_append_align(struct data d, int align)
246{
247 int newlen = DALIGN(d.len, align);
248 return data_append_zeroes(d, newlen - d.len);
249}
250
251struct data data_add_fixup(struct data d, char *ref)
252{
253 struct fixup *f;
254 struct data nd;
255
256 f = xmalloc(sizeof(*f));
257 f->offset = d.len;
258 f->ref = ref;
259 f->next = d.refs;
260
261 nd = d;
262 nd.refs = f;
263
264 return nd;
265}
266
267int data_is_one_string(struct data d)
268{
269 int i;
270 int len = d.len;
271
272 if (len == 0)
273 return 0;
274
275 for (i = 0; i < len-1; i++)
276 if (d.val[i] == '\0')
277 return 0;
278
279 if (d.val[len-1] != '\0')
280 return 0;
281
282 return 1;
283}
284