/src/binutils-gdb/bfd/ppcboot.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* BFD back-end for PPCbug boot records. |
2 | | Copyright (C) 1996-2025 Free Software Foundation, Inc. |
3 | | Written by Michael Meissner, Cygnus Support, <meissner@cygnus.com> |
4 | | |
5 | | This file is part of BFD, the Binary File Descriptor library. |
6 | | |
7 | | This program is free software; you can redistribute it and/or modify |
8 | | it under the terms of the GNU General Public License as published by |
9 | | the Free Software Foundation; either version 3 of the License, or |
10 | | (at your option) any later version. |
11 | | |
12 | | This program is distributed in the hope that it will be useful, |
13 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | GNU General Public License for more details. |
16 | | |
17 | | You should have received a copy of the GNU General Public License |
18 | | along with this program; if not, write to the Free Software |
19 | | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
20 | | MA 02110-1301, USA. */ |
21 | | |
22 | | |
23 | | /* This is a BFD backend which may be used to write PowerPCBug boot objects. |
24 | | It may only be used for output, not input. The intention is that this may |
25 | | be used as an output format for objcopy in order to generate raw binary |
26 | | data. |
27 | | |
28 | | This is very simple. The only complication is that the real data |
29 | | will start at some address X, and in some cases we will not want to |
30 | | include X zeroes just to get to that point. Since the start |
31 | | address is not meaningful for this object file format, we use it |
32 | | instead to indicate the number of zeroes to skip at the start of |
33 | | the file. objcopy cooperates by specially setting the start |
34 | | address to zero by default. */ |
35 | | |
36 | | #include "sysdep.h" |
37 | | #include "safe-ctype.h" |
38 | | #include "bfd.h" |
39 | | #include "libbfd.h" |
40 | | |
41 | | /* PPCbug location structure */ |
42 | | typedef struct ppcboot_location |
43 | | { |
44 | | bfd_byte ind; |
45 | | bfd_byte head; |
46 | | bfd_byte sector; |
47 | | bfd_byte cylinder; |
48 | | } ppcboot_location_t; |
49 | | |
50 | | /* PPCbug partition table layout */ |
51 | | typedef struct ppcboot_partition |
52 | | { |
53 | | ppcboot_location_t partition_begin; /* partition begin */ |
54 | | ppcboot_location_t partition_end; /* partition end */ |
55 | | bfd_byte sector_begin[4]; /* 32-bit start RBA (zero-based), little endian */ |
56 | | bfd_byte sector_length[4]; /* 32-bit RBA count (one-based), little endian */ |
57 | | } ppcboot_partition_t; |
58 | | |
59 | | /* PPCbug boot layout. */ |
60 | | typedef struct ppcboot_hdr |
61 | | { |
62 | | bfd_byte pc_compatibility[446]; /* x86 instruction field */ |
63 | | ppcboot_partition_t partition[4]; /* partition information */ |
64 | | bfd_byte signature[2]; /* 0x55 and 0xaa */ |
65 | | bfd_byte entry_offset[4]; /* entry point offset, little endian */ |
66 | | bfd_byte length[4]; /* load image length, little endian */ |
67 | | bfd_byte flags; /* flag field */ |
68 | | bfd_byte os_id; /* OS_ID */ |
69 | | char partition_name[32]; /* partition name */ |
70 | | bfd_byte reserved1[470]; /* reserved */ |
71 | | } |
72 | | #ifdef __GNUC__ |
73 | | __attribute__ ((packed)) |
74 | | #endif |
75 | | ppcboot_hdr_t; |
76 | | |
77 | | /* Signature bytes for last 2 bytes of the 512 byte record */ |
78 | 844 | #define SIGNATURE0 0x55 |
79 | 1 | #define SIGNATURE1 0xaa |
80 | | |
81 | | /* PowerPC boot type */ |
82 | 1 | #define PPC_IND 0x41 |
83 | | |
84 | | /* Information needed for ppcboot header */ |
85 | | typedef struct ppcboot_data |
86 | | { |
87 | | ppcboot_hdr_t header; /* raw header */ |
88 | | asection *sec; /* single section */ |
89 | | } ppcboot_data_t; |
90 | | |
91 | | /* Any bfd we create by reading a ppcboot file has three symbols: |
92 | | a start symbol, an end symbol, and an absolute length symbol. */ |
93 | 0 | #define PPCBOOT_SYMS 3 |
94 | | |
95 | 0 | #define ppcboot_set_tdata(abfd, ptr) ((abfd)->tdata.any = (ptr)) |
96 | 0 | #define ppcboot_get_tdata(abfd) ((ppcboot_data_t *) ((abfd)->tdata.any)) |
97 | | |
98 | | /* Create a ppcboot object. Invoked via bfd_set_format. */ |
99 | | |
100 | | static bool |
101 | | ppcboot_mkobject (bfd *abfd) |
102 | 0 | { |
103 | 0 | if (!ppcboot_get_tdata (abfd)) |
104 | 0 | { |
105 | 0 | size_t amt = sizeof (ppcboot_data_t); |
106 | 0 | ppcboot_set_tdata (abfd, bfd_zalloc (abfd, amt)); |
107 | 0 | } |
108 | |
|
109 | 0 | return true; |
110 | 0 | } |
111 | | |
112 | | |
113 | | /* Set the architecture to PowerPC */ |
114 | | static bool |
115 | | ppcboot_set_arch_mach (bfd *abfd, |
116 | | enum bfd_architecture arch, |
117 | | unsigned long machine) |
118 | 0 | { |
119 | 0 | if (arch == bfd_arch_unknown) |
120 | 0 | arch = bfd_arch_powerpc; |
121 | | |
122 | 0 | else if (arch != bfd_arch_powerpc) |
123 | 0 | return false; |
124 | | |
125 | 0 | return bfd_default_set_arch_mach (abfd, arch, machine); |
126 | 0 | } |
127 | | |
128 | | |
129 | | /* Any file may be considered to be a ppcboot file, provided the target |
130 | | was not defaulted. That is, it must be explicitly specified as |
131 | | being ppcboot. */ |
132 | | |
133 | | static bfd_cleanup |
134 | | ppcboot_object_p (bfd *abfd) |
135 | 3.41M | { |
136 | 3.41M | struct stat statbuf; |
137 | 3.41M | asection *sec; |
138 | 3.41M | ppcboot_hdr_t hdr; |
139 | 3.41M | size_t i; |
140 | 3.41M | ppcboot_data_t *tdata; |
141 | 3.41M | flagword flags; |
142 | | |
143 | 3.41M | BFD_ASSERT (sizeof (ppcboot_hdr_t) == 1024); |
144 | | |
145 | 3.41M | if (abfd->target_defaulted) |
146 | 103k | { |
147 | 103k | bfd_set_error (bfd_error_wrong_format); |
148 | 103k | return NULL; |
149 | 103k | } |
150 | | |
151 | | /* Find the file size. */ |
152 | 3.30M | if (bfd_stat (abfd, &statbuf) < 0) |
153 | 0 | { |
154 | 0 | bfd_set_error (bfd_error_system_call); |
155 | 0 | return NULL; |
156 | 0 | } |
157 | | |
158 | 3.30M | if ((size_t) statbuf.st_size < sizeof (ppcboot_hdr_t)) |
159 | 2.66M | { |
160 | 2.66M | bfd_set_error (bfd_error_wrong_format); |
161 | 2.66M | return NULL; |
162 | 2.66M | } |
163 | | |
164 | 641k | if (bfd_read (&hdr, sizeof (hdr), abfd) != sizeof (hdr)) |
165 | 58.1k | { |
166 | 58.1k | if (bfd_get_error () != bfd_error_system_call) |
167 | 57.3k | bfd_set_error (bfd_error_wrong_format); |
168 | | |
169 | 58.1k | return NULL; |
170 | 58.1k | } |
171 | | |
172 | | /* Now do some basic checks. */ |
173 | 824k | for (i = 0; i < sizeof (hdr.pc_compatibility); i++) |
174 | 824k | if (hdr.pc_compatibility[i]) |
175 | 582k | { |
176 | 582k | bfd_set_error (bfd_error_wrong_format); |
177 | 582k | return NULL; |
178 | 582k | } |
179 | | |
180 | 422 | if (hdr.signature[0] != SIGNATURE0 || hdr.signature[1] != SIGNATURE1) |
181 | 421 | { |
182 | 421 | bfd_set_error (bfd_error_wrong_format); |
183 | 421 | return NULL; |
184 | 421 | } |
185 | | |
186 | 1 | if (hdr.partition[0].partition_end.ind != PPC_IND) |
187 | 1 | { |
188 | 1 | bfd_set_error (bfd_error_wrong_format); |
189 | 1 | return NULL; |
190 | 1 | } |
191 | | |
192 | 0 | abfd->symcount = PPCBOOT_SYMS; |
193 | | |
194 | | /* One data section. */ |
195 | 0 | flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_CODE | SEC_HAS_CONTENTS; |
196 | 0 | sec = bfd_make_section_with_flags (abfd, ".data", flags); |
197 | 0 | if (sec == NULL) |
198 | 0 | return NULL; |
199 | 0 | sec->vma = 0; |
200 | 0 | sec->size = statbuf.st_size - sizeof (ppcboot_hdr_t); |
201 | 0 | sec->filepos = sizeof (ppcboot_hdr_t); |
202 | |
|
203 | 0 | ppcboot_mkobject (abfd); |
204 | 0 | tdata = ppcboot_get_tdata (abfd); |
205 | 0 | tdata->sec = sec; |
206 | 0 | memcpy (&tdata->header, &hdr, sizeof (ppcboot_hdr_t)); |
207 | |
|
208 | 0 | ppcboot_set_arch_mach (abfd, bfd_arch_powerpc, 0L); |
209 | 0 | return _bfd_no_cleanup; |
210 | 0 | } |
211 | | |
212 | | #define ppcboot_close_and_cleanup _bfd_generic_close_and_cleanup |
213 | | #define ppcboot_bfd_free_cached_info _bfd_generic_bfd_free_cached_info |
214 | | #define ppcboot_new_section_hook _bfd_generic_new_section_hook |
215 | | |
216 | | |
217 | | /* Get contents of the only section. */ |
218 | | |
219 | | static bool |
220 | | ppcboot_get_section_contents (bfd *abfd, |
221 | | asection *section ATTRIBUTE_UNUSED, |
222 | | void * location, |
223 | | file_ptr offset, |
224 | | bfd_size_type count) |
225 | 0 | { |
226 | 0 | if (bfd_seek (abfd, offset + sizeof (ppcboot_hdr_t), SEEK_SET) != 0 |
227 | 0 | || bfd_read (location, count, abfd) != count) |
228 | 0 | return false; |
229 | 0 | return true; |
230 | 0 | } |
231 | | |
232 | | |
233 | | /* Return the amount of memory needed to read the symbol table. */ |
234 | | |
235 | | static long |
236 | | ppcboot_get_symtab_upper_bound (bfd *abfd ATTRIBUTE_UNUSED) |
237 | 0 | { |
238 | 0 | return (PPCBOOT_SYMS + 1) * sizeof (asymbol *); |
239 | 0 | } |
240 | | |
241 | | |
242 | | /* Create a symbol name based on the bfd's filename. */ |
243 | | |
244 | | static char * |
245 | | mangle_name (bfd *abfd, char *suffix) |
246 | 0 | { |
247 | 0 | bfd_size_type size; |
248 | 0 | char *buf; |
249 | 0 | char *p; |
250 | |
|
251 | 0 | size = (strlen (bfd_get_filename (abfd)) |
252 | 0 | + strlen (suffix) |
253 | 0 | + sizeof "_ppcboot__"); |
254 | |
|
255 | 0 | buf = (char *) bfd_alloc (abfd, size); |
256 | 0 | if (buf == NULL) |
257 | 0 | return ""; |
258 | | |
259 | 0 | sprintf (buf, "_ppcboot_%s_%s", bfd_get_filename (abfd), suffix); |
260 | | |
261 | | /* Change any non-alphanumeric characters to underscores. */ |
262 | 0 | for (p = buf; *p; p++) |
263 | 0 | if (! ISALNUM (*p)) |
264 | 0 | *p = '_'; |
265 | |
|
266 | 0 | return buf; |
267 | 0 | } |
268 | | |
269 | | |
270 | | /* Return the symbol table. */ |
271 | | |
272 | | static long |
273 | | ppcboot_canonicalize_symtab (bfd *abfd, asymbol **alocation) |
274 | 0 | { |
275 | 0 | asection *sec = ppcboot_get_tdata (abfd)->sec; |
276 | 0 | asymbol *syms; |
277 | 0 | unsigned int i; |
278 | 0 | size_t amt = PPCBOOT_SYMS * sizeof (asymbol); |
279 | |
|
280 | 0 | syms = (asymbol *) bfd_alloc (abfd, amt); |
281 | 0 | if (syms == NULL) |
282 | 0 | return false; |
283 | | |
284 | | /* Start symbol. */ |
285 | 0 | syms[0].the_bfd = abfd; |
286 | 0 | syms[0].name = mangle_name (abfd, "start"); |
287 | 0 | syms[0].value = 0; |
288 | 0 | syms[0].flags = BSF_GLOBAL; |
289 | 0 | syms[0].section = sec; |
290 | 0 | syms[0].udata.p = NULL; |
291 | | |
292 | | /* End symbol. */ |
293 | 0 | syms[1].the_bfd = abfd; |
294 | 0 | syms[1].name = mangle_name (abfd, "end"); |
295 | 0 | syms[1].value = sec->size; |
296 | 0 | syms[1].flags = BSF_GLOBAL; |
297 | 0 | syms[1].section = sec; |
298 | 0 | syms[1].udata.p = NULL; |
299 | | |
300 | | /* Size symbol. */ |
301 | 0 | syms[2].the_bfd = abfd; |
302 | 0 | syms[2].name = mangle_name (abfd, "size"); |
303 | 0 | syms[2].value = sec->size; |
304 | 0 | syms[2].flags = BSF_GLOBAL; |
305 | 0 | syms[2].section = bfd_abs_section_ptr; |
306 | 0 | syms[2].udata.p = NULL; |
307 | |
|
308 | 0 | for (i = 0; i < PPCBOOT_SYMS; i++) |
309 | 0 | *alocation++ = syms++; |
310 | 0 | *alocation = NULL; |
311 | |
|
312 | 0 | return PPCBOOT_SYMS; |
313 | 0 | } |
314 | | |
315 | | #define ppcboot_make_empty_symbol _bfd_generic_make_empty_symbol |
316 | | #define ppcboot_print_symbol _bfd_nosymbols_print_symbol |
317 | | |
318 | | /* Get information about a symbol. */ |
319 | | |
320 | | static void |
321 | | ppcboot_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED, |
322 | | asymbol *symbol, |
323 | | symbol_info *ret) |
324 | 0 | { |
325 | 0 | bfd_symbol_info (symbol, ret); |
326 | 0 | } |
327 | | |
328 | | #define ppcboot_get_symbol_version_string \ |
329 | | _bfd_nosymbols_get_symbol_version_string |
330 | | #define ppcboot_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false |
331 | | #define ppcboot_bfd_is_local_label_name bfd_generic_is_local_label_name |
332 | | #define ppcboot_get_lineno _bfd_nosymbols_get_lineno |
333 | | #define ppcboot_find_nearest_line _bfd_nosymbols_find_nearest_line |
334 | | #define ppcboot_find_nearest_line_with_alt _bfd_nosymbols_find_nearest_line_with_alt |
335 | | #define ppcboot_find_line _bfd_nosymbols_find_line |
336 | | #define ppcboot_find_inliner_info _bfd_nosymbols_find_inliner_info |
337 | | #define ppcboot_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol |
338 | | #define ppcboot_read_minisymbols _bfd_generic_read_minisymbols |
339 | | #define ppcboot_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol |
340 | | |
341 | | /* Write section contents of a ppcboot file. */ |
342 | | |
343 | | static bool |
344 | | ppcboot_set_section_contents (bfd *abfd, |
345 | | asection *sec, |
346 | | const void * data, |
347 | | file_ptr offset, |
348 | | bfd_size_type size) |
349 | 0 | { |
350 | 0 | if (! abfd->output_has_begun) |
351 | 0 | { |
352 | 0 | bfd_vma low; |
353 | 0 | asection *s; |
354 | | |
355 | | /* The lowest section VMA sets the virtual address of the start |
356 | | of the file. We use the set the file position of all the |
357 | | sections. */ |
358 | 0 | low = abfd->sections->vma; |
359 | 0 | for (s = abfd->sections->next; s != NULL; s = s->next) |
360 | 0 | if (s->vma < low) |
361 | 0 | low = s->vma; |
362 | |
|
363 | 0 | for (s = abfd->sections; s != NULL; s = s->next) |
364 | 0 | s->filepos = s->vma - low; |
365 | |
|
366 | 0 | abfd->output_has_begun = true; |
367 | 0 | } |
368 | |
|
369 | 0 | return _bfd_generic_set_section_contents (abfd, sec, data, offset, size); |
370 | 0 | } |
371 | | |
372 | | |
373 | | static int |
374 | | ppcboot_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, |
375 | | struct bfd_link_info *info ATTRIBUTE_UNUSED) |
376 | 0 | { |
377 | 0 | return sizeof (ppcboot_hdr_t); |
378 | 0 | } |
379 | | |
380 | | |
381 | | /* Print out the program headers. */ |
382 | | |
383 | | static bool |
384 | | ppcboot_bfd_print_private_bfd_data (bfd *abfd, void * farg) |
385 | 0 | { |
386 | 0 | FILE *f = (FILE *)farg; |
387 | 0 | ppcboot_data_t *tdata = ppcboot_get_tdata (abfd); |
388 | 0 | long entry_offset = bfd_getl_signed_32 (tdata->header.entry_offset); |
389 | 0 | long length = bfd_getl_signed_32 (tdata->header.length); |
390 | 0 | int i; |
391 | |
|
392 | 0 | fprintf (f, _("\nppcboot header:\n")); |
393 | 0 | fprintf (f, _("Entry offset = 0x%.8lx (%ld)\n"), |
394 | 0 | (unsigned long) entry_offset, entry_offset); |
395 | 0 | fprintf (f, _("Length = 0x%.8lx (%ld)\n"), |
396 | 0 | (unsigned long) length, length); |
397 | |
|
398 | 0 | if (tdata->header.flags) |
399 | 0 | fprintf (f, _("Flag field = 0x%.2x\n"), tdata->header.flags); |
400 | |
|
401 | 0 | if (tdata->header.os_id) |
402 | 0 | fprintf (f, "OS_ID = 0x%.2x\n", tdata->header.os_id); |
403 | |
|
404 | 0 | if (tdata->header.partition_name[0]) |
405 | 0 | fprintf (f, _("Partition name = \"%s\"\n"), tdata->header.partition_name); |
406 | |
|
407 | 0 | for (i = 0; i < 4; i++) |
408 | 0 | { |
409 | 0 | long sector_begin = bfd_getl_signed_32 (tdata->header.partition[i].sector_begin); |
410 | 0 | long sector_length = bfd_getl_signed_32 (tdata->header.partition[i].sector_length); |
411 | | |
412 | | /* Skip all 0 entries */ |
413 | 0 | if (!tdata->header.partition[i].partition_begin.ind |
414 | 0 | && !tdata->header.partition[i].partition_begin.head |
415 | 0 | && !tdata->header.partition[i].partition_begin.sector |
416 | 0 | && !tdata->header.partition[i].partition_begin.cylinder |
417 | 0 | && !tdata->header.partition[i].partition_end.ind |
418 | 0 | && !tdata->header.partition[i].partition_end.head |
419 | 0 | && !tdata->header.partition[i].partition_end.sector |
420 | 0 | && !tdata->header.partition[i].partition_end.cylinder |
421 | 0 | && !sector_begin && !sector_length) |
422 | 0 | continue; |
423 | | |
424 | | /* xgettext:c-format */ |
425 | 0 | fprintf (f, _("\nPartition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"), i, |
426 | 0 | tdata->header.partition[i].partition_begin.ind, |
427 | 0 | tdata->header.partition[i].partition_begin.head, |
428 | 0 | tdata->header.partition[i].partition_begin.sector, |
429 | 0 | tdata->header.partition[i].partition_begin.cylinder); |
430 | | |
431 | | /* xgettext:c-format */ |
432 | 0 | fprintf (f, _("Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"), i, |
433 | 0 | tdata->header.partition[i].partition_end.ind, |
434 | 0 | tdata->header.partition[i].partition_end.head, |
435 | 0 | tdata->header.partition[i].partition_end.sector, |
436 | 0 | tdata->header.partition[i].partition_end.cylinder); |
437 | | |
438 | | /* xgettext:c-format */ |
439 | 0 | fprintf (f, _("Partition[%d] sector = 0x%.8lx (%ld)\n"), |
440 | 0 | i, (unsigned long) sector_begin, sector_begin); |
441 | | |
442 | | /* xgettext:c-format */ |
443 | 0 | fprintf (f, _("Partition[%d] length = 0x%.8lx (%ld)\n"), |
444 | 0 | i, (unsigned long) sector_length, sector_length); |
445 | 0 | } |
446 | |
|
447 | 0 | fprintf (f, "\n"); |
448 | 0 | return true; |
449 | 0 | } |
450 | | |
451 | | |
452 | | #define ppcboot_bfd_get_relocated_section_contents \ |
453 | | bfd_generic_get_relocated_section_contents |
454 | | #define ppcboot_bfd_relax_section bfd_generic_relax_section |
455 | | #define ppcboot_bfd_gc_sections bfd_generic_gc_sections |
456 | | #define ppcboot_bfd_lookup_section_flags bfd_generic_lookup_section_flags |
457 | | #define ppcboot_bfd_merge_sections bfd_generic_merge_sections |
458 | | #define ppcboot_bfd_is_group_section bfd_generic_is_group_section |
459 | | #define ppcboot_bfd_group_name bfd_generic_group_name |
460 | | #define ppcboot_bfd_discard_group bfd_generic_discard_group |
461 | | #define ppcboot_section_already_linked \ |
462 | | _bfd_generic_section_already_linked |
463 | | #define ppcboot_bfd_define_common_symbol bfd_generic_define_common_symbol |
464 | | #define ppcboot_bfd_link_hide_symbol _bfd_generic_link_hide_symbol |
465 | | #define ppcboot_bfd_define_start_stop bfd_generic_define_start_stop |
466 | | #define ppcboot_bfd_link_hash_table_create _bfd_generic_link_hash_table_create |
467 | | #define ppcboot_bfd_link_add_symbols _bfd_generic_link_add_symbols |
468 | | #define ppcboot_bfd_link_just_syms _bfd_generic_link_just_syms |
469 | | #define ppcboot_bfd_copy_link_hash_symbol_type \ |
470 | | _bfd_generic_copy_link_hash_symbol_type |
471 | | #define ppcboot_bfd_final_link _bfd_generic_final_link |
472 | | #define ppcboot_bfd_link_split_section _bfd_generic_link_split_section |
473 | | #define ppcboot_bfd_link_check_relocs _bfd_generic_link_check_relocs |
474 | | |
475 | | #define ppcboot_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data |
476 | | #define ppcboot_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data |
477 | | #define ppcboot_init_private_section_data _bfd_generic_init_private_section_data |
478 | | #define ppcboot_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data |
479 | | #define ppcboot_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data |
480 | | #define ppcboot_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data |
481 | | #define ppcboot_bfd_set_private_flags _bfd_generic_bfd_set_private_flags |
482 | | #define ppcboot_bfd_print_private_bfd_dat ppcboot_bfd_print_private_bfd_data |
483 | | |
484 | | const bfd_target powerpc_boot_vec = |
485 | | { |
486 | | "ppcboot", /* name */ |
487 | | bfd_target_unknown_flavour, /* flavour */ |
488 | | BFD_ENDIAN_BIG, /* byteorder is big endian for code */ |
489 | | BFD_ENDIAN_LITTLE, /* header_byteorder */ |
490 | | EXEC_P, /* object_flags */ |
491 | | (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA |
492 | | | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */ |
493 | | 0, /* symbol_leading_char */ |
494 | | ' ', /* ar_pad_char */ |
495 | | 16, /* ar_max_namelen */ |
496 | | 0, /* match priority. */ |
497 | | TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */ |
498 | | bfd_getb64, bfd_getb_signed_64, bfd_putb64, |
499 | | bfd_getb32, bfd_getb_signed_32, bfd_putb32, |
500 | | bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ |
501 | | bfd_getl64, bfd_getl_signed_64, bfd_putl64, |
502 | | bfd_getl32, bfd_getl_signed_32, bfd_putl32, |
503 | | bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ |
504 | | { /* bfd_check_format */ |
505 | | _bfd_dummy_target, |
506 | | ppcboot_object_p, /* bfd_check_format */ |
507 | | _bfd_dummy_target, |
508 | | _bfd_dummy_target, |
509 | | }, |
510 | | { /* bfd_set_format */ |
511 | | _bfd_bool_bfd_false_error, |
512 | | ppcboot_mkobject, |
513 | | _bfd_bool_bfd_false_error, |
514 | | _bfd_bool_bfd_false_error, |
515 | | }, |
516 | | { /* bfd_write_contents */ |
517 | | _bfd_bool_bfd_false_error, |
518 | | _bfd_bool_bfd_true, |
519 | | _bfd_bool_bfd_false_error, |
520 | | _bfd_bool_bfd_false_error, |
521 | | }, |
522 | | |
523 | | BFD_JUMP_TABLE_GENERIC (ppcboot), |
524 | | BFD_JUMP_TABLE_COPY (ppcboot), |
525 | | BFD_JUMP_TABLE_CORE (_bfd_nocore), |
526 | | BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), |
527 | | BFD_JUMP_TABLE_SYMBOLS (ppcboot), |
528 | | BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), |
529 | | BFD_JUMP_TABLE_WRITE (ppcboot), |
530 | | BFD_JUMP_TABLE_LINK (ppcboot), |
531 | | BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), |
532 | | |
533 | | NULL, |
534 | | |
535 | | NULL |
536 | | }; |