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