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