ppcboot.c revision 77298
160484Sobrien/* BFD back-end for PPCbug boot records.
260484Sobrien   Copyright 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
360484Sobrien   Written by Michael Meissner, Cygnus Support, <meissner@cygnus.com>
460484Sobrien
560484SobrienThis file is part of BFD, the Binary File Descriptor library.
660484Sobrien
760484SobrienThis program is free software; you can redistribute it and/or modify
860484Sobrienit under the terms of the GNU General Public License as published by
960484Sobrienthe Free Software Foundation; either version 2 of the License, or
1060484Sobrien(at your option) any later version.
1160484Sobrien
1260484SobrienThis program is distributed in the hope that it will be useful,
1360484Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1460484SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1560484SobrienGNU General Public License for more details.
1660484Sobrien
1760484SobrienYou should have received a copy of the GNU General Public License
1860484Sobrienalong with this program; if not, write to the Free Software
1960484SobrienFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2060484Sobrien
2160484Sobrien/* This is a BFD backend which may be used to write PowerPCBug boot objects.
2260484Sobrien   It may only be used for output, not input.  The intention is that this may
2360484Sobrien   be used as an output format for objcopy in order to generate raw binary
2460484Sobrien   data.
2560484Sobrien
2660484Sobrien   This is very simple.  The only complication is that the real data
2760484Sobrien   will start at some address X, and in some cases we will not want to
2860484Sobrien   include X zeroes just to get to that point.  Since the start
2960484Sobrien   address is not meaningful for this object file format, we use it
3060484Sobrien   instead to indicate the number of zeroes to skip at the start of
3160484Sobrien   the file.  objcopy cooperates by specially setting the start
3260484Sobrien   address to zero by default.  */
3360484Sobrien
3460484Sobrien#include <ctype.h>
3560484Sobrien
3660484Sobrien#include "bfd.h"
3760484Sobrien#include "sysdep.h"
3860484Sobrien#include "libbfd.h"
3960484Sobrien
4060484Sobrien/* PPCbug location structure */
4160484Sobrientypedef struct ppcboot_location {
4260484Sobrien  bfd_byte	ind;
4360484Sobrien  bfd_byte	head;
4460484Sobrien  bfd_byte	sector;
4560484Sobrien  bfd_byte	cylinder;
4660484Sobrien} ppcboot_location_t;
4760484Sobrien
4860484Sobrien/* PPCbug partition table layout */
4960484Sobrientypedef struct ppcboot_partition {
5060484Sobrien  ppcboot_location_t	partition_begin;	/* partition begin */
5160484Sobrien  ppcboot_location_t	partition_end;		/* partition end */
5260484Sobrien  bfd_byte		sector_begin[4];	/* 32-bit start RBA (zero-based), little endian */
5360484Sobrien  bfd_byte		sector_length[4];	/* 32-bit RBA count (one-based), little endian */
5460484Sobrien} ppcboot_partition_t;
5560484Sobrien
5660484Sobrien/* PPCbug boot layout.  */
5760484Sobrientypedef struct ppcboot_hdr {
5860484Sobrien  bfd_byte		pc_compatibility[446];	/* x86 instruction field */
5960484Sobrien  ppcboot_partition_t	partition[4];		/* partition information */
6060484Sobrien  bfd_byte		signature[2];		/* 0x55 and 0xaa */
6160484Sobrien  bfd_byte		entry_offset[4];	/* entry point offset, little endian */
6260484Sobrien  bfd_byte		length[4];		/* load image length, little endian */
6360484Sobrien  bfd_byte		flags;			/* flag field */
6460484Sobrien  bfd_byte		os_id;			/* OS_ID */
6560484Sobrien  char			partition_name[32];	/* partition name */
6660484Sobrien  bfd_byte		reserved1[470];		/* reserved */
6761843Sobrien}
6861843Sobrien#ifdef __GNUC__
6961843Sobrien  __attribute__ ((packed))
7061843Sobrien#endif
7161843Sobrienppcboot_hdr_t;
7260484Sobrien
7360484Sobrien/* Signature bytes for last 2 bytes of the 512 byte record */
7460484Sobrien#define SIGNATURE0 0x55
7560484Sobrien#define SIGNATURE1 0xaa
7660484Sobrien
7760484Sobrien/* PowerPC boot type */
7860484Sobrien#define PPC_IND 0x41
7960484Sobrien
8060484Sobrien/* Information needed for ppcboot header */
8160484Sobrientypedef struct ppcboot_data {
8260484Sobrien  ppcboot_hdr_t	header;				/* raw header */
8360484Sobrien  asection *sec;				/* single section */
8460484Sobrien} ppcboot_data_t;
8560484Sobrien
8660484Sobrien/* Any bfd we create by reading a ppcboot file has three symbols:
8760484Sobrien   a start symbol, an end symbol, and an absolute length symbol.  */
8860484Sobrien#define PPCBOOT_SYMS 3
8960484Sobrien
9060484Sobrienstatic boolean ppcboot_mkobject PARAMS ((bfd *));
9160484Sobrienstatic const bfd_target *ppcboot_object_p PARAMS ((bfd *));
9260484Sobrienstatic boolean ppcboot_set_arch_mach
9360484Sobrien  PARAMS ((bfd *, enum bfd_architecture, unsigned long));
9460484Sobrienstatic boolean ppcboot_get_section_contents
9560484Sobrien  PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
9660484Sobrienstatic long ppcboot_get_symtab_upper_bound PARAMS ((bfd *));
9760484Sobrienstatic char *mangle_name PARAMS ((bfd *, char *));
9860484Sobrienstatic long ppcboot_get_symtab PARAMS ((bfd *, asymbol **));
9960484Sobrienstatic asymbol *ppcboot_make_empty_symbol PARAMS ((bfd *));
10060484Sobrienstatic void ppcboot_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
10160484Sobrienstatic boolean ppcboot_set_section_contents
10260484Sobrien  PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
10360484Sobrienstatic int ppcboot_sizeof_headers PARAMS ((bfd *, boolean));
10460484Sobrienstatic boolean ppcboot_bfd_print_private_bfd_data PARAMS ((bfd *, PTR));
10560484Sobrien
10660484Sobrien#define ppcboot_set_tdata(abfd, ptr) ((abfd)->tdata.any = (PTR) (ptr))
10760484Sobrien#define ppcboot_get_tdata(abfd) ((ppcboot_data_t *) ((abfd)->tdata.any))
10860484Sobrien
10960484Sobrien/* Create a ppcboot object.  Invoked via bfd_set_format.  */
11060484Sobrien
11160484Sobrienstatic boolean
11260484Sobrienppcboot_mkobject (abfd)
11360484Sobrien     bfd *abfd;
11460484Sobrien{
11560484Sobrien  if (!ppcboot_get_tdata (abfd))
11660484Sobrien    ppcboot_set_tdata (abfd, bfd_zalloc (abfd, sizeof (ppcboot_data_t)));
11760484Sobrien
11860484Sobrien  return true;
11960484Sobrien}
12060484Sobrien
12160484Sobrien
12260484Sobrien/* Set the architecture to PowerPC */
12360484Sobrienstatic boolean
12460484Sobrienppcboot_set_arch_mach (abfd, arch, machine)
12560484Sobrien     bfd *abfd;
12660484Sobrien     enum bfd_architecture arch;
12760484Sobrien     unsigned long machine;
12860484Sobrien{
12960484Sobrien  if (arch == bfd_arch_unknown)
13060484Sobrien    arch = bfd_arch_powerpc;
13160484Sobrien
13260484Sobrien  else if (arch != bfd_arch_powerpc)
13360484Sobrien    return false;
13460484Sobrien
13560484Sobrien  return bfd_default_set_arch_mach (abfd, arch, machine);
13660484Sobrien}
13760484Sobrien
13860484Sobrien
13960484Sobrien/* Any file may be considered to be a ppcboot file, provided the target
14060484Sobrien   was not defaulted.  That is, it must be explicitly specified as
14160484Sobrien   being ppcboot.  */
14260484Sobrien
14360484Sobrienstatic const bfd_target *
14460484Sobrienppcboot_object_p (abfd)
14560484Sobrien     bfd *abfd;
14660484Sobrien{
14760484Sobrien  struct stat statbuf;
14860484Sobrien  asection *sec;
14960484Sobrien  ppcboot_hdr_t hdr;
15060484Sobrien  size_t i;
15160484Sobrien  ppcboot_data_t *tdata;
15260484Sobrien
15360484Sobrien  BFD_ASSERT (sizeof (ppcboot_hdr_t) == 1024);
15460484Sobrien
15560484Sobrien  if (abfd->target_defaulted)
15660484Sobrien    {
15760484Sobrien      bfd_set_error (bfd_error_wrong_format);
15860484Sobrien      return NULL;
15960484Sobrien    }
16060484Sobrien
16160484Sobrien  /* Find the file size.  */
16260484Sobrien  if (bfd_stat (abfd, &statbuf) < 0)
16360484Sobrien    {
16460484Sobrien      bfd_set_error (bfd_error_system_call);
16560484Sobrien      return NULL;
16660484Sobrien    }
16760484Sobrien
16860484Sobrien  if ((size_t) statbuf.st_size < sizeof (ppcboot_hdr_t))
16960484Sobrien    {
17060484Sobrien      bfd_set_error (bfd_error_wrong_format);
17160484Sobrien      return NULL;
17260484Sobrien    }
17360484Sobrien
17460484Sobrien  if (bfd_read ((PTR) &hdr, sizeof (hdr), 1, abfd) != sizeof (hdr))
17560484Sobrien    {
17660484Sobrien      if (bfd_get_error () != bfd_error_system_call)
17760484Sobrien	bfd_set_error (bfd_error_wrong_format);
17860484Sobrien
17960484Sobrien      return NULL;
18060484Sobrien    }
18160484Sobrien
18260484Sobrien  /* Now do some basic checks.  */
18360484Sobrien  for (i = 0; i < sizeof (hdr.pc_compatibility); i++)
18460484Sobrien    if (hdr.pc_compatibility[i])
18560484Sobrien      {
18660484Sobrien	bfd_set_error (bfd_error_wrong_format);
18760484Sobrien	return NULL;
18860484Sobrien      }
18960484Sobrien
19060484Sobrien  if (hdr.signature[0] != SIGNATURE0 || hdr.signature[1] != SIGNATURE1)
19160484Sobrien    {
19260484Sobrien      bfd_set_error (bfd_error_wrong_format);
19360484Sobrien      return NULL;
19460484Sobrien    }
19560484Sobrien
19660484Sobrien  if (hdr.partition[0].partition_end.ind != PPC_IND)
19760484Sobrien    {
19860484Sobrien      bfd_set_error (bfd_error_wrong_format);
19960484Sobrien      return NULL;
20060484Sobrien    }
20160484Sobrien
20260484Sobrien  abfd->symcount = PPCBOOT_SYMS;
20360484Sobrien
20460484Sobrien  /* One data section.  */
20560484Sobrien  sec = bfd_make_section (abfd, ".data");
20660484Sobrien  if (sec == NULL)
20760484Sobrien    return NULL;
20860484Sobrien  sec->flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_CODE | SEC_HAS_CONTENTS;
20960484Sobrien  sec->vma = 0;
21060484Sobrien  sec->_raw_size = statbuf.st_size - sizeof (ppcboot_hdr_t);
21160484Sobrien  sec->filepos = sizeof (ppcboot_hdr_t);
21260484Sobrien
21360484Sobrien  ppcboot_mkobject (abfd);
21460484Sobrien  tdata = ppcboot_get_tdata (abfd);
21560484Sobrien  tdata->sec = sec;
21660484Sobrien  memcpy ((PTR) &tdata->header, (PTR) &hdr, sizeof (ppcboot_hdr_t));
21760484Sobrien
21860484Sobrien  ppcboot_set_arch_mach (abfd, bfd_arch_powerpc, 0);
21960484Sobrien  return abfd->xvec;
22060484Sobrien}
22160484Sobrien
22260484Sobrien#define ppcboot_close_and_cleanup _bfd_generic_close_and_cleanup
22360484Sobrien#define ppcboot_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
22460484Sobrien#define ppcboot_new_section_hook _bfd_generic_new_section_hook
22560484Sobrien
22660484Sobrien
22760484Sobrien/* Get contents of the only section.  */
22860484Sobrien
22960484Sobrienstatic boolean
23060484Sobrienppcboot_get_section_contents (abfd, section, location, offset, count)
23160484Sobrien     bfd *abfd;
23260484Sobrien     asection *section ATTRIBUTE_UNUSED;
23360484Sobrien     PTR location;
23460484Sobrien     file_ptr offset;
23560484Sobrien     bfd_size_type count;
23660484Sobrien{
23777298Sobrien  if (bfd_seek (abfd, offset + sizeof (ppcboot_hdr_t), SEEK_SET) != 0
23860484Sobrien      || bfd_read (location, 1, count, abfd) != count)
23960484Sobrien    return false;
24060484Sobrien  return true;
24160484Sobrien}
24260484Sobrien
24360484Sobrien
24460484Sobrien/* Return the amount of memory needed to read the symbol table.  */
24560484Sobrien
24660484Sobrienstatic long
24760484Sobrienppcboot_get_symtab_upper_bound (abfd)
24860484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
24960484Sobrien{
25060484Sobrien  return (PPCBOOT_SYMS + 1) * sizeof (asymbol *);
25160484Sobrien}
25260484Sobrien
25360484Sobrien
25460484Sobrien/* Create a symbol name based on the bfd's filename.  */
25560484Sobrien
25660484Sobrienstatic char *
25760484Sobrienmangle_name (abfd, suffix)
25860484Sobrien     bfd *abfd;
25960484Sobrien     char *suffix;
26060484Sobrien{
26160484Sobrien  int size;
26260484Sobrien  char *buf;
26360484Sobrien  char *p;
26460484Sobrien
26560484Sobrien  size = (strlen (bfd_get_filename (abfd))
26660484Sobrien	  + strlen (suffix)
26760484Sobrien	  + sizeof "_ppcboot__");
26860484Sobrien
26960484Sobrien  buf = (char *) bfd_alloc (abfd, size);
27060484Sobrien  if (buf == NULL)
27160484Sobrien    return "";
27260484Sobrien
27360484Sobrien  sprintf (buf, "_ppcboot_%s_%s", bfd_get_filename (abfd), suffix);
27460484Sobrien
27560484Sobrien  /* Change any non-alphanumeric characters to underscores.  */
27660484Sobrien  for (p = buf; *p; p++)
27760484Sobrien    if (! isalnum ((unsigned char) *p))
27860484Sobrien      *p = '_';
27960484Sobrien
28060484Sobrien  return buf;
28160484Sobrien}
28260484Sobrien
28360484Sobrien
28460484Sobrien/* Return the symbol table.  */
28560484Sobrien
28660484Sobrienstatic long
28760484Sobrienppcboot_get_symtab (abfd, alocation)
28860484Sobrien     bfd *abfd;
28960484Sobrien     asymbol **alocation;
29060484Sobrien{
29160484Sobrien  asection *sec = ppcboot_get_tdata (abfd)->sec;
29260484Sobrien  asymbol *syms;
29360484Sobrien  unsigned int i;
29460484Sobrien
29560484Sobrien  syms = (asymbol *) bfd_alloc (abfd, PPCBOOT_SYMS * sizeof (asymbol));
29660484Sobrien  if (syms == NULL)
29760484Sobrien    return false;
29860484Sobrien
29960484Sobrien  /* Start symbol.  */
30060484Sobrien  syms[0].the_bfd = abfd;
30160484Sobrien  syms[0].name = mangle_name (abfd, "start");
30260484Sobrien  syms[0].value = 0;
30360484Sobrien  syms[0].flags = BSF_GLOBAL;
30460484Sobrien  syms[0].section = sec;
30560484Sobrien  syms[0].udata.p = NULL;
30660484Sobrien
30760484Sobrien  /* End symbol.  */
30860484Sobrien  syms[1].the_bfd = abfd;
30960484Sobrien  syms[1].name = mangle_name (abfd, "end");
31060484Sobrien  syms[1].value = sec->_raw_size;
31160484Sobrien  syms[1].flags = BSF_GLOBAL;
31260484Sobrien  syms[1].section = sec;
31360484Sobrien  syms[1].udata.p = NULL;
31460484Sobrien
31560484Sobrien  /* Size symbol.  */
31660484Sobrien  syms[2].the_bfd = abfd;
31760484Sobrien  syms[2].name = mangle_name (abfd, "size");
31860484Sobrien  syms[2].value = sec->_raw_size;
31960484Sobrien  syms[2].flags = BSF_GLOBAL;
32060484Sobrien  syms[2].section = bfd_abs_section_ptr;
32160484Sobrien  syms[2].udata.p = NULL;
32260484Sobrien
32360484Sobrien  for (i = 0; i < PPCBOOT_SYMS; i++)
32460484Sobrien    *alocation++ = syms++;
32560484Sobrien  *alocation = NULL;
32660484Sobrien
32760484Sobrien  return PPCBOOT_SYMS;
32860484Sobrien}
32960484Sobrien
33060484Sobrien
33160484Sobrien/* Make an empty symbol.  */
33260484Sobrien
33360484Sobrienstatic asymbol *
33460484Sobrienppcboot_make_empty_symbol (abfd)
33560484Sobrien     bfd *abfd;
33660484Sobrien{
33760484Sobrien  return (asymbol *) bfd_alloc (abfd, sizeof (asymbol));
33860484Sobrien}
33960484Sobrien
34060484Sobrien
34160484Sobrien#define ppcboot_print_symbol _bfd_nosymbols_print_symbol
34260484Sobrien
34360484Sobrien/* Get information about a symbol.  */
34460484Sobrien
34560484Sobrienstatic void
34660484Sobrienppcboot_get_symbol_info (ignore_abfd, symbol, ret)
34760484Sobrien     bfd *ignore_abfd ATTRIBUTE_UNUSED;
34860484Sobrien     asymbol *symbol;
34960484Sobrien     symbol_info *ret;
35060484Sobrien{
35160484Sobrien  bfd_symbol_info (symbol, ret);
35260484Sobrien}
35360484Sobrien
35460484Sobrien#define ppcboot_bfd_is_local_label_name bfd_generic_is_local_label_name
35560484Sobrien#define ppcboot_get_lineno _bfd_nosymbols_get_lineno
35660484Sobrien#define ppcboot_find_nearest_line _bfd_nosymbols_find_nearest_line
35760484Sobrien#define ppcboot_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
35860484Sobrien#define ppcboot_read_minisymbols _bfd_generic_read_minisymbols
35960484Sobrien#define ppcboot_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
36060484Sobrien
36160484Sobrien#define ppcboot_get_reloc_upper_bound \
36260484Sobrien  ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
36360484Sobrien#define ppcboot_canonicalize_reloc \
36460484Sobrien  ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
36560484Sobrien#define ppcboot_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
36660484Sobrien
36760484Sobrien/* Write section contents of a ppcboot file.  */
36860484Sobrien
36960484Sobrienstatic boolean
37060484Sobrienppcboot_set_section_contents (abfd, sec, data, offset, size)
37160484Sobrien     bfd *abfd;
37260484Sobrien     asection *sec;
37360484Sobrien     PTR data;
37460484Sobrien     file_ptr offset;
37560484Sobrien     bfd_size_type size;
37660484Sobrien{
37760484Sobrien  if (! abfd->output_has_begun)
37860484Sobrien    {
37960484Sobrien      bfd_vma low;
38060484Sobrien      asection *s;
38160484Sobrien
38260484Sobrien      /* The lowest section VMA sets the virtual address of the start
38360484Sobrien         of the file.  We use the set the file position of all the
38460484Sobrien         sections.  */
38560484Sobrien      low = abfd->sections->vma;
38660484Sobrien      for (s = abfd->sections->next; s != NULL; s = s->next)
38760484Sobrien	if (s->vma < low)
38860484Sobrien	  low = s->vma;
38960484Sobrien
39060484Sobrien      for (s = abfd->sections; s != NULL; s = s->next)
39160484Sobrien	s->filepos = s->vma - low;
39260484Sobrien
39360484Sobrien      abfd->output_has_begun = true;
39460484Sobrien    }
39560484Sobrien
39660484Sobrien  return _bfd_generic_set_section_contents (abfd, sec, data, offset, size);
39760484Sobrien}
39860484Sobrien
39960484Sobrien
40060484Sobrienstatic int
40160484Sobrienppcboot_sizeof_headers (abfd, exec)
40260484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
40360484Sobrien     boolean exec ATTRIBUTE_UNUSED;
40460484Sobrien{
40560484Sobrien  return sizeof (ppcboot_hdr_t);
40660484Sobrien}
40760484Sobrien
40860484Sobrien
40960484Sobrien/* Print out the program headers.  */
41060484Sobrien
41160484Sobrienstatic boolean
41260484Sobrienppcboot_bfd_print_private_bfd_data (abfd, farg)
41360484Sobrien     bfd *abfd;
41460484Sobrien     PTR farg;
41560484Sobrien{
41660484Sobrien  FILE *f = (FILE *)farg;
41760484Sobrien  ppcboot_data_t *tdata = ppcboot_get_tdata (abfd);
41860484Sobrien  long entry_offset = bfd_getl_signed_32 ((PTR) tdata->header.entry_offset);
41960484Sobrien  long length = bfd_getl_signed_32 ((PTR) tdata->header.length);
42060484Sobrien  int i;
42160484Sobrien
42260484Sobrien  fprintf (f, _("\nppcboot header:\n"));
42360484Sobrien  fprintf (f, _("Entry offset        = 0x%.8lx (%ld)\n"), entry_offset, entry_offset);
42460484Sobrien  fprintf (f, _("Length              = 0x%.8lx (%ld)\n"), length, length);
42560484Sobrien
42660484Sobrien  if (tdata->header.flags)
42760484Sobrien    fprintf (f, _("Flag field          = 0x%.2x\n"), tdata->header.flags);
42860484Sobrien
42960484Sobrien  if (tdata->header.os_id)
43060484Sobrien    fprintf (f, "OS_ID               = 0x%.2x\n", tdata->header.os_id);
43160484Sobrien
43260484Sobrien  if (tdata->header.partition_name)
43360484Sobrien    fprintf (f, _("Partition name      = \"%s\"\n"), tdata->header.partition_name);
43460484Sobrien
43560484Sobrien  for (i = 0; i < 4; i++)
43660484Sobrien    {
43760484Sobrien      long sector_begin  = bfd_getl_signed_32 ((PTR) tdata->header.partition[i].sector_begin);
43860484Sobrien      long sector_length = bfd_getl_signed_32 ((PTR) tdata->header.partition[i].sector_length);
43960484Sobrien
44060484Sobrien      /* Skip all 0 entries */
44160484Sobrien      if (!tdata->header.partition[i].partition_begin.ind
44260484Sobrien	  && !tdata->header.partition[i].partition_begin.head
44360484Sobrien	  && !tdata->header.partition[i].partition_begin.sector
44460484Sobrien	  && !tdata->header.partition[i].partition_begin.cylinder
44560484Sobrien	  && !tdata->header.partition[i].partition_end.ind
44660484Sobrien	  && !tdata->header.partition[i].partition_end.head
44760484Sobrien	  && !tdata->header.partition[i].partition_end.sector
44860484Sobrien	  && !tdata->header.partition[i].partition_end.cylinder
44960484Sobrien	  && !sector_begin && !sector_length)
45060484Sobrien	continue;
45160484Sobrien
45260484Sobrien      fprintf (f, _("\nPartition[%d] start  = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"), i,
45360484Sobrien	       tdata->header.partition[i].partition_begin.ind,
45460484Sobrien	       tdata->header.partition[i].partition_begin.head,
45560484Sobrien	       tdata->header.partition[i].partition_begin.sector,
45660484Sobrien	       tdata->header.partition[i].partition_begin.cylinder);
45760484Sobrien
45860484Sobrien      fprintf (f, _("Partition[%d] end    = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"), i,
45960484Sobrien	       tdata->header.partition[i].partition_end.ind,
46060484Sobrien	       tdata->header.partition[i].partition_end.head,
46160484Sobrien	       tdata->header.partition[i].partition_end.sector,
46260484Sobrien	       tdata->header.partition[i].partition_end.cylinder);
46360484Sobrien
46460484Sobrien      fprintf (f, _("Partition[%d] sector = 0x%.8lx (%ld)\n"), i, sector_begin, sector_begin);
46560484Sobrien      fprintf (f, _("Partition[%d] length = 0x%.8lx (%ld)\n"), i, sector_length, sector_length);
46660484Sobrien    }
46760484Sobrien
46860484Sobrien  fprintf (f, "\n");
46960484Sobrien  return true;
47060484Sobrien}
47160484Sobrien
47260484Sobrien
47360484Sobrien#define ppcboot_bfd_get_relocated_section_contents \
47460484Sobrien  bfd_generic_get_relocated_section_contents
47560484Sobrien#define ppcboot_bfd_relax_section bfd_generic_relax_section
47660484Sobrien#define ppcboot_bfd_gc_sections bfd_generic_gc_sections
47760484Sobrien#define ppcboot_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
47860484Sobrien#define ppcboot_bfd_link_add_symbols _bfd_generic_link_add_symbols
47960484Sobrien#define ppcboot_bfd_final_link _bfd_generic_final_link
48060484Sobrien#define ppcboot_bfd_link_split_section _bfd_generic_link_split_section
48160484Sobrien#define ppcboot_get_section_contents_in_window \
48260484Sobrien  _bfd_generic_get_section_contents_in_window
48360484Sobrien
48460484Sobrien#define ppcboot_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
48560484Sobrien#define ppcboot_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
48660484Sobrien#define ppcboot_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
48760484Sobrien#define ppcboot_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
48860484Sobrien#define ppcboot_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
48960484Sobrien#define ppcboot_bfd_print_private_bfd_dat ppcboot_bfd_print_private_bfd_data
49060484Sobrien
49160484Sobrienconst bfd_target ppcboot_vec =
49260484Sobrien{
49360484Sobrien  "ppcboot",			/* name */
49460484Sobrien  bfd_target_unknown_flavour,	/* flavour */
49560484Sobrien  BFD_ENDIAN_BIG,		/* byteorder is big endian for code */
49660484Sobrien  BFD_ENDIAN_LITTLE,		/* header_byteorder */
49760484Sobrien  EXEC_P,			/* object_flags */
49860484Sobrien  (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
49960484Sobrien   | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */
50060484Sobrien  0,				/* symbol_leading_char */
50160484Sobrien  ' ',				/* ar_pad_char */
50260484Sobrien  16,				/* ar_max_namelen */
50360484Sobrien  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
50460484Sobrien  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
50560484Sobrien  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* data */
50660484Sobrien  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
50760484Sobrien  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
50860484Sobrien  bfd_getl16, bfd_getl_signed_16, bfd_putl16,	/* hdrs */
50960484Sobrien  {				/* bfd_check_format */
51060484Sobrien    _bfd_dummy_target,
51160484Sobrien    ppcboot_object_p,		/* bfd_check_format */
51260484Sobrien    _bfd_dummy_target,
51360484Sobrien    _bfd_dummy_target,
51460484Sobrien  },
51560484Sobrien  {				/* bfd_set_format */
51660484Sobrien    bfd_false,
51760484Sobrien    ppcboot_mkobject,
51860484Sobrien    bfd_false,
51960484Sobrien    bfd_false,
52060484Sobrien  },
52160484Sobrien  {				/* bfd_write_contents */
52260484Sobrien    bfd_false,
52360484Sobrien    bfd_true,
52460484Sobrien    bfd_false,
52560484Sobrien    bfd_false,
52660484Sobrien  },
52760484Sobrien
52860484Sobrien  BFD_JUMP_TABLE_GENERIC (ppcboot),
52960484Sobrien  BFD_JUMP_TABLE_COPY (ppcboot),
53060484Sobrien  BFD_JUMP_TABLE_CORE (_bfd_nocore),
53160484Sobrien  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
53260484Sobrien  BFD_JUMP_TABLE_SYMBOLS (ppcboot),
53360484Sobrien  BFD_JUMP_TABLE_RELOCS (ppcboot),
53460484Sobrien  BFD_JUMP_TABLE_WRITE (ppcboot),
53560484Sobrien  BFD_JUMP_TABLE_LINK (ppcboot),
53660484Sobrien  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
53760484Sobrien
53860484Sobrien  NULL,
53977298Sobrien
54060484Sobrien  NULL
54160484Sobrien};
542