ppcboot.c revision 60484
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 */
6760484Sobrien} ppcboot_hdr_t;
6860484Sobrien
6960484Sobrien/* Signature bytes for last 2 bytes of the 512 byte record */
7060484Sobrien#define SIGNATURE0 0x55
7160484Sobrien#define SIGNATURE1 0xaa
7260484Sobrien
7360484Sobrien/* PowerPC boot type */
7460484Sobrien#define PPC_IND 0x41
7560484Sobrien
7660484Sobrien/* Information needed for ppcboot header */
7760484Sobrientypedef struct ppcboot_data {
7860484Sobrien  ppcboot_hdr_t	header;				/* raw header */
7960484Sobrien  asection *sec;				/* single section */
8060484Sobrien} ppcboot_data_t;
8160484Sobrien
8260484Sobrien/* Any bfd we create by reading a ppcboot file has three symbols:
8360484Sobrien   a start symbol, an end symbol, and an absolute length symbol.  */
8460484Sobrien#define PPCBOOT_SYMS 3
8560484Sobrien
8660484Sobrienstatic boolean ppcboot_mkobject PARAMS ((bfd *));
8760484Sobrienstatic const bfd_target *ppcboot_object_p PARAMS ((bfd *));
8860484Sobrienstatic boolean ppcboot_set_arch_mach
8960484Sobrien  PARAMS ((bfd *, enum bfd_architecture, unsigned long));
9060484Sobrienstatic boolean ppcboot_get_section_contents
9160484Sobrien  PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
9260484Sobrienstatic long ppcboot_get_symtab_upper_bound PARAMS ((bfd *));
9360484Sobrienstatic char *mangle_name PARAMS ((bfd *, char *));
9460484Sobrienstatic long ppcboot_get_symtab PARAMS ((bfd *, asymbol **));
9560484Sobrienstatic asymbol *ppcboot_make_empty_symbol PARAMS ((bfd *));
9660484Sobrienstatic void ppcboot_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
9760484Sobrienstatic boolean ppcboot_set_section_contents
9860484Sobrien  PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
9960484Sobrienstatic int ppcboot_sizeof_headers PARAMS ((bfd *, boolean));
10060484Sobrienstatic boolean ppcboot_bfd_print_private_bfd_data PARAMS ((bfd *, PTR));
10160484Sobrien
10260484Sobrien#define ppcboot_set_tdata(abfd, ptr) ((abfd)->tdata.any = (PTR) (ptr))
10360484Sobrien#define ppcboot_get_tdata(abfd) ((ppcboot_data_t *) ((abfd)->tdata.any))
10460484Sobrien
10560484Sobrien/* Create a ppcboot object.  Invoked via bfd_set_format.  */
10660484Sobrien
10760484Sobrienstatic boolean
10860484Sobrienppcboot_mkobject (abfd)
10960484Sobrien     bfd *abfd;
11060484Sobrien{
11160484Sobrien  if (!ppcboot_get_tdata (abfd))
11260484Sobrien    ppcboot_set_tdata (abfd, bfd_zalloc (abfd, sizeof (ppcboot_data_t)));
11360484Sobrien
11460484Sobrien  return true;
11560484Sobrien}
11660484Sobrien
11760484Sobrien
11860484Sobrien/* Set the architecture to PowerPC */
11960484Sobrienstatic boolean
12060484Sobrienppcboot_set_arch_mach (abfd, arch, machine)
12160484Sobrien     bfd *abfd;
12260484Sobrien     enum bfd_architecture arch;
12360484Sobrien     unsigned long machine;
12460484Sobrien{
12560484Sobrien  if (arch == bfd_arch_unknown)
12660484Sobrien    arch = bfd_arch_powerpc;
12760484Sobrien
12860484Sobrien  else if (arch != bfd_arch_powerpc)
12960484Sobrien    return false;
13060484Sobrien
13160484Sobrien  return bfd_default_set_arch_mach (abfd, arch, machine);
13260484Sobrien}
13360484Sobrien
13460484Sobrien
13560484Sobrien/* Any file may be considered to be a ppcboot file, provided the target
13660484Sobrien   was not defaulted.  That is, it must be explicitly specified as
13760484Sobrien   being ppcboot.  */
13860484Sobrien
13960484Sobrienstatic const bfd_target *
14060484Sobrienppcboot_object_p (abfd)
14160484Sobrien     bfd *abfd;
14260484Sobrien{
14360484Sobrien  struct stat statbuf;
14460484Sobrien  asection *sec;
14560484Sobrien  ppcboot_hdr_t hdr;
14660484Sobrien  size_t i;
14760484Sobrien  ppcboot_data_t *tdata;
14860484Sobrien
14960484Sobrien  BFD_ASSERT (sizeof (ppcboot_hdr_t) == 1024);
15060484Sobrien
15160484Sobrien  if (abfd->target_defaulted)
15260484Sobrien    {
15360484Sobrien      bfd_set_error (bfd_error_wrong_format);
15460484Sobrien      return NULL;
15560484Sobrien    }
15660484Sobrien
15760484Sobrien  /* Find the file size.  */
15860484Sobrien  if (bfd_stat (abfd, &statbuf) < 0)
15960484Sobrien    {
16060484Sobrien      bfd_set_error (bfd_error_system_call);
16160484Sobrien      return NULL;
16260484Sobrien    }
16360484Sobrien
16460484Sobrien  if ((size_t) statbuf.st_size < sizeof (ppcboot_hdr_t))
16560484Sobrien    {
16660484Sobrien      bfd_set_error (bfd_error_wrong_format);
16760484Sobrien      return NULL;
16860484Sobrien    }
16960484Sobrien
17060484Sobrien  if (bfd_read ((PTR) &hdr, sizeof (hdr), 1, abfd) != sizeof (hdr))
17160484Sobrien    {
17260484Sobrien      if (bfd_get_error () != bfd_error_system_call)
17360484Sobrien	bfd_set_error (bfd_error_wrong_format);
17460484Sobrien
17560484Sobrien      return NULL;
17660484Sobrien    }
17760484Sobrien
17860484Sobrien  /* Now do some basic checks.  */
17960484Sobrien  for (i = 0; i < sizeof (hdr.pc_compatibility); i++)
18060484Sobrien    if (hdr.pc_compatibility[i])
18160484Sobrien      {
18260484Sobrien	bfd_set_error (bfd_error_wrong_format);
18360484Sobrien	return NULL;
18460484Sobrien      }
18560484Sobrien
18660484Sobrien  if (hdr.signature[0] != SIGNATURE0 || hdr.signature[1] != SIGNATURE1)
18760484Sobrien    {
18860484Sobrien      bfd_set_error (bfd_error_wrong_format);
18960484Sobrien      return NULL;
19060484Sobrien    }
19160484Sobrien
19260484Sobrien  if (hdr.partition[0].partition_end.ind != PPC_IND)
19360484Sobrien    {
19460484Sobrien      bfd_set_error (bfd_error_wrong_format);
19560484Sobrien      return NULL;
19660484Sobrien    }
19760484Sobrien
19860484Sobrien  abfd->symcount = PPCBOOT_SYMS;
19960484Sobrien
20060484Sobrien  /* One data section.  */
20160484Sobrien  sec = bfd_make_section (abfd, ".data");
20260484Sobrien  if (sec == NULL)
20360484Sobrien    return NULL;
20460484Sobrien  sec->flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_CODE | SEC_HAS_CONTENTS;
20560484Sobrien  sec->vma = 0;
20660484Sobrien  sec->_raw_size = statbuf.st_size - sizeof (ppcboot_hdr_t);
20760484Sobrien  sec->filepos = sizeof (ppcboot_hdr_t);
20860484Sobrien
20960484Sobrien  ppcboot_mkobject (abfd);
21060484Sobrien  tdata = ppcboot_get_tdata (abfd);
21160484Sobrien  tdata->sec = sec;
21260484Sobrien  memcpy ((PTR) &tdata->header, (PTR) &hdr, sizeof (ppcboot_hdr_t));
21360484Sobrien
21460484Sobrien  ppcboot_set_arch_mach (abfd, bfd_arch_powerpc, 0);
21560484Sobrien  return abfd->xvec;
21660484Sobrien}
21760484Sobrien
21860484Sobrien#define ppcboot_close_and_cleanup _bfd_generic_close_and_cleanup
21960484Sobrien#define ppcboot_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
22060484Sobrien#define ppcboot_new_section_hook _bfd_generic_new_section_hook
22160484Sobrien
22260484Sobrien
22360484Sobrien/* Get contents of the only section.  */
22460484Sobrien
22560484Sobrienstatic boolean
22660484Sobrienppcboot_get_section_contents (abfd, section, location, offset, count)
22760484Sobrien     bfd *abfd;
22860484Sobrien     asection *section ATTRIBUTE_UNUSED;
22960484Sobrien     PTR location;
23060484Sobrien     file_ptr offset;
23160484Sobrien     bfd_size_type count;
23260484Sobrien{
23360484Sobrien  if (bfd_seek (abfd, offset + sizeof(ppcboot_hdr_t), SEEK_SET) != 0
23460484Sobrien      || bfd_read (location, 1, count, abfd) != count)
23560484Sobrien    return false;
23660484Sobrien  return true;
23760484Sobrien}
23860484Sobrien
23960484Sobrien
24060484Sobrien/* Return the amount of memory needed to read the symbol table.  */
24160484Sobrien
24260484Sobrienstatic long
24360484Sobrienppcboot_get_symtab_upper_bound (abfd)
24460484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
24560484Sobrien{
24660484Sobrien  return (PPCBOOT_SYMS + 1) * sizeof (asymbol *);
24760484Sobrien}
24860484Sobrien
24960484Sobrien
25060484Sobrien/* Create a symbol name based on the bfd's filename.  */
25160484Sobrien
25260484Sobrienstatic char *
25360484Sobrienmangle_name (abfd, suffix)
25460484Sobrien     bfd *abfd;
25560484Sobrien     char *suffix;
25660484Sobrien{
25760484Sobrien  int size;
25860484Sobrien  char *buf;
25960484Sobrien  char *p;
26060484Sobrien
26160484Sobrien  size = (strlen (bfd_get_filename (abfd))
26260484Sobrien	  + strlen (suffix)
26360484Sobrien	  + sizeof "_ppcboot__");
26460484Sobrien
26560484Sobrien  buf = (char *) bfd_alloc (abfd, size);
26660484Sobrien  if (buf == NULL)
26760484Sobrien    return "";
26860484Sobrien
26960484Sobrien  sprintf (buf, "_ppcboot_%s_%s", bfd_get_filename (abfd), suffix);
27060484Sobrien
27160484Sobrien  /* Change any non-alphanumeric characters to underscores.  */
27260484Sobrien  for (p = buf; *p; p++)
27360484Sobrien    if (! isalnum ((unsigned char) *p))
27460484Sobrien      *p = '_';
27560484Sobrien
27660484Sobrien  return buf;
27760484Sobrien}
27860484Sobrien
27960484Sobrien
28060484Sobrien/* Return the symbol table.  */
28160484Sobrien
28260484Sobrienstatic long
28360484Sobrienppcboot_get_symtab (abfd, alocation)
28460484Sobrien     bfd *abfd;
28560484Sobrien     asymbol **alocation;
28660484Sobrien{
28760484Sobrien  asection *sec = ppcboot_get_tdata (abfd)->sec;
28860484Sobrien  asymbol *syms;
28960484Sobrien  unsigned int i;
29060484Sobrien
29160484Sobrien  syms = (asymbol *) bfd_alloc (abfd, PPCBOOT_SYMS * sizeof (asymbol));
29260484Sobrien  if (syms == NULL)
29360484Sobrien    return false;
29460484Sobrien
29560484Sobrien  /* Start symbol.  */
29660484Sobrien  syms[0].the_bfd = abfd;
29760484Sobrien  syms[0].name = mangle_name (abfd, "start");
29860484Sobrien  syms[0].value = 0;
29960484Sobrien  syms[0].flags = BSF_GLOBAL;
30060484Sobrien  syms[0].section = sec;
30160484Sobrien  syms[0].udata.p = NULL;
30260484Sobrien
30360484Sobrien  /* End symbol.  */
30460484Sobrien  syms[1].the_bfd = abfd;
30560484Sobrien  syms[1].name = mangle_name (abfd, "end");
30660484Sobrien  syms[1].value = sec->_raw_size;
30760484Sobrien  syms[1].flags = BSF_GLOBAL;
30860484Sobrien  syms[1].section = sec;
30960484Sobrien  syms[1].udata.p = NULL;
31060484Sobrien
31160484Sobrien  /* Size symbol.  */
31260484Sobrien  syms[2].the_bfd = abfd;
31360484Sobrien  syms[2].name = mangle_name (abfd, "size");
31460484Sobrien  syms[2].value = sec->_raw_size;
31560484Sobrien  syms[2].flags = BSF_GLOBAL;
31660484Sobrien  syms[2].section = bfd_abs_section_ptr;
31760484Sobrien  syms[2].udata.p = NULL;
31860484Sobrien
31960484Sobrien  for (i = 0; i < PPCBOOT_SYMS; i++)
32060484Sobrien    *alocation++ = syms++;
32160484Sobrien  *alocation = NULL;
32260484Sobrien
32360484Sobrien  return PPCBOOT_SYMS;
32460484Sobrien}
32560484Sobrien
32660484Sobrien
32760484Sobrien/* Make an empty symbol.  */
32860484Sobrien
32960484Sobrienstatic asymbol *
33060484Sobrienppcboot_make_empty_symbol (abfd)
33160484Sobrien     bfd *abfd;
33260484Sobrien{
33360484Sobrien  return (asymbol *) bfd_alloc (abfd, sizeof (asymbol));
33460484Sobrien}
33560484Sobrien
33660484Sobrien
33760484Sobrien#define ppcboot_print_symbol _bfd_nosymbols_print_symbol
33860484Sobrien
33960484Sobrien/* Get information about a symbol.  */
34060484Sobrien
34160484Sobrienstatic void
34260484Sobrienppcboot_get_symbol_info (ignore_abfd, symbol, ret)
34360484Sobrien     bfd *ignore_abfd ATTRIBUTE_UNUSED;
34460484Sobrien     asymbol *symbol;
34560484Sobrien     symbol_info *ret;
34660484Sobrien{
34760484Sobrien  bfd_symbol_info (symbol, ret);
34860484Sobrien}
34960484Sobrien
35060484Sobrien#define ppcboot_bfd_is_local_label_name bfd_generic_is_local_label_name
35160484Sobrien#define ppcboot_get_lineno _bfd_nosymbols_get_lineno
35260484Sobrien#define ppcboot_find_nearest_line _bfd_nosymbols_find_nearest_line
35360484Sobrien#define ppcboot_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
35460484Sobrien#define ppcboot_read_minisymbols _bfd_generic_read_minisymbols
35560484Sobrien#define ppcboot_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
35660484Sobrien
35760484Sobrien#define ppcboot_get_reloc_upper_bound \
35860484Sobrien  ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
35960484Sobrien#define ppcboot_canonicalize_reloc \
36060484Sobrien  ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
36160484Sobrien#define ppcboot_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
36260484Sobrien
36360484Sobrien/* Write section contents of a ppcboot file.  */
36460484Sobrien
36560484Sobrienstatic boolean
36660484Sobrienppcboot_set_section_contents (abfd, sec, data, offset, size)
36760484Sobrien     bfd *abfd;
36860484Sobrien     asection *sec;
36960484Sobrien     PTR data;
37060484Sobrien     file_ptr offset;
37160484Sobrien     bfd_size_type size;
37260484Sobrien{
37360484Sobrien  if (! abfd->output_has_begun)
37460484Sobrien    {
37560484Sobrien      bfd_vma low;
37660484Sobrien      asection *s;
37760484Sobrien
37860484Sobrien      /* The lowest section VMA sets the virtual address of the start
37960484Sobrien         of the file.  We use the set the file position of all the
38060484Sobrien         sections.  */
38160484Sobrien      low = abfd->sections->vma;
38260484Sobrien      for (s = abfd->sections->next; s != NULL; s = s->next)
38360484Sobrien	if (s->vma < low)
38460484Sobrien	  low = s->vma;
38560484Sobrien
38660484Sobrien      for (s = abfd->sections; s != NULL; s = s->next)
38760484Sobrien	s->filepos = s->vma - low;
38860484Sobrien
38960484Sobrien      abfd->output_has_begun = true;
39060484Sobrien    }
39160484Sobrien
39260484Sobrien  return _bfd_generic_set_section_contents (abfd, sec, data, offset, size);
39360484Sobrien}
39460484Sobrien
39560484Sobrien
39660484Sobrienstatic int
39760484Sobrienppcboot_sizeof_headers (abfd, exec)
39860484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
39960484Sobrien     boolean exec ATTRIBUTE_UNUSED;
40060484Sobrien{
40160484Sobrien  return sizeof (ppcboot_hdr_t);
40260484Sobrien}
40360484Sobrien
40460484Sobrien
40560484Sobrien/* Print out the program headers.  */
40660484Sobrien
40760484Sobrienstatic boolean
40860484Sobrienppcboot_bfd_print_private_bfd_data (abfd, farg)
40960484Sobrien     bfd *abfd;
41060484Sobrien     PTR farg;
41160484Sobrien{
41260484Sobrien  FILE *f = (FILE *)farg;
41360484Sobrien  ppcboot_data_t *tdata = ppcboot_get_tdata (abfd);
41460484Sobrien  long entry_offset = bfd_getl_signed_32 ((PTR) tdata->header.entry_offset);
41560484Sobrien  long length = bfd_getl_signed_32 ((PTR) tdata->header.length);
41660484Sobrien  int i;
41760484Sobrien
41860484Sobrien  fprintf (f, _("\nppcboot header:\n"));
41960484Sobrien  fprintf (f, _("Entry offset        = 0x%.8lx (%ld)\n"), entry_offset, entry_offset);
42060484Sobrien  fprintf (f, _("Length              = 0x%.8lx (%ld)\n"), length, length);
42160484Sobrien
42260484Sobrien  if (tdata->header.flags)
42360484Sobrien    fprintf (f, _("Flag field          = 0x%.2x\n"), tdata->header.flags);
42460484Sobrien
42560484Sobrien  if (tdata->header.os_id)
42660484Sobrien    fprintf (f, "OS_ID               = 0x%.2x\n", tdata->header.os_id);
42760484Sobrien
42860484Sobrien  if (tdata->header.partition_name)
42960484Sobrien    fprintf (f, _("Partition name      = \"%s\"\n"), tdata->header.partition_name);
43060484Sobrien
43160484Sobrien  for (i = 0; i < 4; i++)
43260484Sobrien    {
43360484Sobrien      long sector_begin  = bfd_getl_signed_32 ((PTR) tdata->header.partition[i].sector_begin);
43460484Sobrien      long sector_length = bfd_getl_signed_32 ((PTR) tdata->header.partition[i].sector_length);
43560484Sobrien
43660484Sobrien      /* Skip all 0 entries */
43760484Sobrien      if (!tdata->header.partition[i].partition_begin.ind
43860484Sobrien	  && !tdata->header.partition[i].partition_begin.head
43960484Sobrien	  && !tdata->header.partition[i].partition_begin.sector
44060484Sobrien	  && !tdata->header.partition[i].partition_begin.cylinder
44160484Sobrien	  && !tdata->header.partition[i].partition_end.ind
44260484Sobrien	  && !tdata->header.partition[i].partition_end.head
44360484Sobrien	  && !tdata->header.partition[i].partition_end.sector
44460484Sobrien	  && !tdata->header.partition[i].partition_end.cylinder
44560484Sobrien	  && !sector_begin && !sector_length)
44660484Sobrien	continue;
44760484Sobrien
44860484Sobrien      fprintf (f, _("\nPartition[%d] start  = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"), i,
44960484Sobrien	       tdata->header.partition[i].partition_begin.ind,
45060484Sobrien	       tdata->header.partition[i].partition_begin.head,
45160484Sobrien	       tdata->header.partition[i].partition_begin.sector,
45260484Sobrien	       tdata->header.partition[i].partition_begin.cylinder);
45360484Sobrien
45460484Sobrien      fprintf (f, _("Partition[%d] end    = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"), i,
45560484Sobrien	       tdata->header.partition[i].partition_end.ind,
45660484Sobrien	       tdata->header.partition[i].partition_end.head,
45760484Sobrien	       tdata->header.partition[i].partition_end.sector,
45860484Sobrien	       tdata->header.partition[i].partition_end.cylinder);
45960484Sobrien
46060484Sobrien      fprintf (f, _("Partition[%d] sector = 0x%.8lx (%ld)\n"), i, sector_begin, sector_begin);
46160484Sobrien      fprintf (f, _("Partition[%d] length = 0x%.8lx (%ld)\n"), i, sector_length, sector_length);
46260484Sobrien    }
46360484Sobrien
46460484Sobrien  fprintf (f, "\n");
46560484Sobrien  return true;
46660484Sobrien}
46760484Sobrien
46860484Sobrien
46960484Sobrien#define ppcboot_bfd_get_relocated_section_contents \
47060484Sobrien  bfd_generic_get_relocated_section_contents
47160484Sobrien#define ppcboot_bfd_relax_section bfd_generic_relax_section
47260484Sobrien#define ppcboot_bfd_gc_sections bfd_generic_gc_sections
47360484Sobrien#define ppcboot_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
47460484Sobrien#define ppcboot_bfd_link_add_symbols _bfd_generic_link_add_symbols
47560484Sobrien#define ppcboot_bfd_final_link _bfd_generic_final_link
47660484Sobrien#define ppcboot_bfd_link_split_section _bfd_generic_link_split_section
47760484Sobrien#define ppcboot_get_section_contents_in_window \
47860484Sobrien  _bfd_generic_get_section_contents_in_window
47960484Sobrien
48060484Sobrien#define ppcboot_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
48160484Sobrien#define ppcboot_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
48260484Sobrien#define ppcboot_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
48360484Sobrien#define ppcboot_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
48460484Sobrien#define ppcboot_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
48560484Sobrien#define ppcboot_bfd_print_private_bfd_dat ppcboot_bfd_print_private_bfd_data
48660484Sobrien
48760484Sobrienconst bfd_target ppcboot_vec =
48860484Sobrien{
48960484Sobrien  "ppcboot",			/* name */
49060484Sobrien  bfd_target_unknown_flavour,	/* flavour */
49160484Sobrien  BFD_ENDIAN_BIG,		/* byteorder is big endian for code */
49260484Sobrien  BFD_ENDIAN_LITTLE,		/* header_byteorder */
49360484Sobrien  EXEC_P,			/* object_flags */
49460484Sobrien  (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
49560484Sobrien   | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */
49660484Sobrien  0,				/* symbol_leading_char */
49760484Sobrien  ' ',				/* ar_pad_char */
49860484Sobrien  16,				/* ar_max_namelen */
49960484Sobrien  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
50060484Sobrien  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
50160484Sobrien  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* data */
50260484Sobrien  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
50360484Sobrien  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
50460484Sobrien  bfd_getl16, bfd_getl_signed_16, bfd_putl16,	/* hdrs */
50560484Sobrien  {				/* bfd_check_format */
50660484Sobrien    _bfd_dummy_target,
50760484Sobrien    ppcboot_object_p,		/* bfd_check_format */
50860484Sobrien    _bfd_dummy_target,
50960484Sobrien    _bfd_dummy_target,
51060484Sobrien  },
51160484Sobrien  {				/* bfd_set_format */
51260484Sobrien    bfd_false,
51360484Sobrien    ppcboot_mkobject,
51460484Sobrien    bfd_false,
51560484Sobrien    bfd_false,
51660484Sobrien  },
51760484Sobrien  {				/* bfd_write_contents */
51860484Sobrien    bfd_false,
51960484Sobrien    bfd_true,
52060484Sobrien    bfd_false,
52160484Sobrien    bfd_false,
52260484Sobrien  },
52360484Sobrien
52460484Sobrien  BFD_JUMP_TABLE_GENERIC (ppcboot),
52560484Sobrien  BFD_JUMP_TABLE_COPY (ppcboot),
52660484Sobrien  BFD_JUMP_TABLE_CORE (_bfd_nocore),
52760484Sobrien  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
52860484Sobrien  BFD_JUMP_TABLE_SYMBOLS (ppcboot),
52960484Sobrien  BFD_JUMP_TABLE_RELOCS (ppcboot),
53060484Sobrien  BFD_JUMP_TABLE_WRITE (ppcboot),
53160484Sobrien  BFD_JUMP_TABLE_LINK (ppcboot),
53260484Sobrien  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
53360484Sobrien
53460484Sobrien  NULL,
53560484Sobrien
53660484Sobrien  NULL
53760484Sobrien};
538