]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/dtc/dtb.cc
vtfontcvt: whitespace cleanup
[FreeBSD/FreeBSD.git] / usr.bin / dtc / dtb.cc
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2013 David Chisnall
5  * All rights reserved.
6  *
7  * This software was developed by SRI International and the University of
8  * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
9  * ("CTSRD"), as part of the DARPA CRASH research programme.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $FreeBSD$
33  */
34
35 #include "dtb.hh"
36 #include <sys/types.h>
37 #include <inttypes.h>
38 #include <stdio.h>
39 #include <unistd.h>
40
41 using std::string;
42
43 namespace dtc
44 {
45 namespace dtb
46 {
47
48 void output_writer::write_data(byte_buffer b)
49 {
50         for (auto i : b)
51         {
52                 write_data(i);
53         }
54 }
55
56 void
57 binary_writer::write_string(const string &name)
58 {
59         push_string(buffer, name);
60         // Trailing nul
61         buffer.push_back(0);
62 }
63
64 void
65 binary_writer::write_data(uint8_t v)
66 {
67         buffer.push_back(v);
68 }
69
70 void
71 binary_writer::write_data(uint32_t v)
72 {
73         while (buffer.size() % 4 != 0)
74         {
75                 buffer.push_back(0);
76         }
77         push_big_endian(buffer, v);
78 }
79
80 void
81 binary_writer::write_data(uint64_t v)
82 {
83         while (buffer.size() % 8 != 0)
84         {
85                 buffer.push_back(0);
86         }
87         push_big_endian(buffer, v);
88 }
89
90 void
91 binary_writer::write_to_file(int fd)
92 {
93         // FIXME: Check return
94         write(fd, buffer.data(), buffer.size());
95 }
96
97 uint32_t
98 binary_writer::size()
99 {
100         return buffer.size();
101 }
102
103 void
104 asm_writer::write_line(const char *c)
105 {
106         if (byte_count != 0)
107         {
108                 byte_count = 0;
109                 buffer.push_back('\n');
110         }
111         write_string(c);
112 }
113
114 void
115 asm_writer::write_byte(uint8_t b)
116 {
117         char out[3] = {0};
118         if (byte_count++ == 0)
119         {
120                 buffer.push_back('\t');
121         }
122         write_string(".byte 0x");
123         snprintf(out, 3, "%.2hhx", b);
124         buffer.push_back(out[0]);
125         buffer.push_back(out[1]);
126         if (byte_count == 4)
127         {
128                 buffer.push_back('\n');
129                 byte_count = 0;
130         }
131         else
132         {
133                 buffer.push_back(';');
134                 buffer.push_back(' ');
135         }
136 }
137
138 void
139 asm_writer::write_label(const string &name)
140 {
141         write_line("\t.globl ");
142         push_string(buffer, name);
143         buffer.push_back('\n');
144         push_string(buffer, name);
145         buffer.push_back(':');
146         buffer.push_back('\n');
147         buffer.push_back('_');
148         push_string(buffer, name);
149         buffer.push_back(':');
150         buffer.push_back('\n');
151         
152 }
153
154 void
155 asm_writer::write_comment(const string &name)
156 {
157         write_line("\t/* ");
158         push_string(buffer, name);
159         write_string(" */\n");
160 }
161
162 void
163 asm_writer::write_string(const char *c)
164 {
165         while (*c)
166         {
167                 buffer.push_back((uint8_t)*(c++));
168         }
169 }
170
171
172 void
173 asm_writer::write_string(const string &name)
174 {
175         write_line("\t.string \"");
176         push_string(buffer, name);
177         write_line("\"\n");
178         bytes_written += name.size() + 1;
179 }
180
181 void
182 asm_writer::write_data(uint8_t v)
183 {
184         write_byte(v);
185         bytes_written++;
186 }
187
188 void
189 asm_writer::write_data(uint32_t v)
190 {
191         if (bytes_written % 4 != 0)
192         {
193                 write_line("\t.balign 4\n");
194                 bytes_written += (4 - (bytes_written % 4));
195         }
196         write_byte((v >> 24) & 0xff);
197         write_byte((v >> 16) & 0xff);
198         write_byte((v >> 8) & 0xff);
199         write_byte((v >> 0) & 0xff);
200         bytes_written += 4;
201 }
202
203 void
204 asm_writer::write_data(uint64_t v)
205 {
206         if (bytes_written % 8 != 0)
207         {
208                 write_line("\t.balign 8\n");
209                 bytes_written += (8 - (bytes_written % 8));
210         }
211         write_byte((v >> 56) & 0xff);
212         write_byte((v >> 48) & 0xff);
213         write_byte((v >> 40) & 0xff);
214         write_byte((v >> 32) & 0xff);
215         write_byte((v >> 24) & 0xff);
216         write_byte((v >> 16) & 0xff);
217         write_byte((v >> 8) & 0xff);
218         write_byte((v >> 0) & 0xff);
219         bytes_written += 8;
220 }
221
222 void
223 asm_writer::write_to_file(int fd)
224 {
225         // FIXME: Check return
226         write(fd, buffer.data(), buffer.size());
227 }
228
229 uint32_t
230 asm_writer::size()
231 {
232         return bytes_written;
233 }
234
235 void
236 header::write(output_writer &out)
237 {
238         out.write_label("dt_blob_start");
239         out.write_label("dt_header");
240         out.write_comment("magic");
241         out.write_data(magic);
242         out.write_comment("totalsize");
243         out.write_data(totalsize);
244         out.write_comment("off_dt_struct");
245         out.write_data(off_dt_struct);
246         out.write_comment("off_dt_strings");
247         out.write_data(off_dt_strings);
248         out.write_comment("off_mem_rsvmap");
249         out.write_data(off_mem_rsvmap);
250         out.write_comment("version");
251         out.write_data(version);
252         out.write_comment("last_comp_version");
253         out.write_data(last_comp_version);
254         out.write_comment("boot_cpuid_phys");
255         out.write_data(boot_cpuid_phys);
256         out.write_comment("size_dt_strings");
257         out.write_data(size_dt_strings);
258         out.write_comment("size_dt_struct");
259         out.write_data(size_dt_struct);
260 }
261
262 bool
263 header::read_dtb(input_buffer &input)
264 {
265         if (!input.consume_binary(magic))
266         {
267                 fprintf(stderr, "Missing magic token in header.");
268                 return false;
269         }
270         if (magic != 0xd00dfeed)
271         {
272                 fprintf(stderr, "Bad magic token in header.  Got %" PRIx32
273                                 " expected 0xd00dfeed\n", magic);
274                 return false;
275         }
276         return input.consume_binary(totalsize) &&
277                input.consume_binary(off_dt_struct) &&
278                input.consume_binary(off_dt_strings) &&
279                input.consume_binary(off_mem_rsvmap) &&
280                input.consume_binary(version) &&
281                input.consume_binary(last_comp_version) &&
282                input.consume_binary(boot_cpuid_phys) &&
283                input.consume_binary(size_dt_strings) &&
284                input.consume_binary(size_dt_struct);
285 }
286 uint32_t
287 string_table::add_string(const string &str)
288 {
289         auto old = string_offsets.find(str);
290         if (old == string_offsets.end())
291         {
292                 uint32_t start = size;
293                 // Don't forget the trailing nul
294                 size += str.size() + 1;
295                 string_offsets.insert(std::make_pair(str, start));
296                 strings.push_back(str);
297                 return start;
298         }
299         else
300         {
301                 return old->second;
302         }
303 }
304
305 void
306 string_table::write(dtb::output_writer &writer)
307 {
308         writer.write_comment("Strings table.");
309         writer.write_label("dt_strings_start");
310         for (auto &i : strings)
311         {
312                 writer.write_string(i);
313         }
314         writer.write_label("dt_strings_end");
315 }
316
317 } // namespace dtb
318
319 } // namespace dtc
320