ppcboot.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 543 行 · 第 1/2 页

C
543
字号
/* BFD back-end for PPCbug boot records.   Copyright 1996, 1997, 1998, 1999, 2000, 2001   Free Software Foundation, Inc.   Written by Michael Meissner, Cygnus Support, <meissner@cygnus.com>This file is part of BFD, the Binary File Descriptor library.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  *//* This is a BFD backend which may be used to write PowerPCBug boot objects.   It may only be used for output, not input.  The intention is that this may   be used as an output format for objcopy in order to generate raw binary   data.   This is very simple.  The only complication is that the real data   will start at some address X, and in some cases we will not want to   include X zeroes just to get to that point.  Since the start   address is not meaningful for this object file format, we use it   instead to indicate the number of zeroes to skip at the start of   the file.  objcopy cooperates by specially setting the start   address to zero by default.  */#include <ctype.h>#include "bfd.h"#include "sysdep.h"#include "libbfd.h"/* PPCbug location structure */typedef struct ppcboot_location {  bfd_byte	ind;  bfd_byte	head;  bfd_byte	sector;  bfd_byte	cylinder;} ppcboot_location_t;/* PPCbug partition table layout */typedef struct ppcboot_partition {  ppcboot_location_t	partition_begin;	/* partition begin */  ppcboot_location_t	partition_end;		/* partition end */  bfd_byte		sector_begin[4];	/* 32-bit start RBA (zero-based), little endian */  bfd_byte		sector_length[4];	/* 32-bit RBA count (one-based), little endian */} ppcboot_partition_t;/* PPCbug boot layout.  */typedef struct ppcboot_hdr {  bfd_byte		pc_compatibility[446];	/* x86 instruction field */  ppcboot_partition_t	partition[4];		/* partition information */  bfd_byte		signature[2];		/* 0x55 and 0xaa */  bfd_byte		entry_offset[4];	/* entry point offset, little endian */  bfd_byte		length[4];		/* load image length, little endian */  bfd_byte		flags;			/* flag field */  bfd_byte		os_id;			/* OS_ID */  char			partition_name[32];	/* partition name */  bfd_byte		reserved1[470];		/* reserved */}#ifdef __GNUC__  __attribute__ ((packed))#endifppcboot_hdr_t;/* Signature bytes for last 2 bytes of the 512 byte record */#define SIGNATURE0 0x55#define SIGNATURE1 0xaa/* PowerPC boot type */#define PPC_IND 0x41/* Information needed for ppcboot header */typedef struct ppcboot_data {  ppcboot_hdr_t	header;				/* raw header */  asection *sec;				/* single section */} ppcboot_data_t;/* Any bfd we create by reading a ppcboot file has three symbols:   a start symbol, an end symbol, and an absolute length symbol.  */#define PPCBOOT_SYMS 3static boolean ppcboot_mkobject PARAMS ((bfd *));static const bfd_target *ppcboot_object_p PARAMS ((bfd *));static boolean ppcboot_set_arch_mach  PARAMS ((bfd *, enum bfd_architecture, unsigned long));static boolean ppcboot_get_section_contents  PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));static long ppcboot_get_symtab_upper_bound PARAMS ((bfd *));static char *mangle_name PARAMS ((bfd *, char *));static long ppcboot_get_symtab PARAMS ((bfd *, asymbol **));static asymbol *ppcboot_make_empty_symbol PARAMS ((bfd *));static void ppcboot_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));static boolean ppcboot_set_section_contents  PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));static int ppcboot_sizeof_headers PARAMS ((bfd *, boolean));static boolean ppcboot_bfd_print_private_bfd_data PARAMS ((bfd *, PTR));#define ppcboot_set_tdata(abfd, ptr) ((abfd)->tdata.any = (PTR) (ptr))#define ppcboot_get_tdata(abfd) ((ppcboot_data_t *) ((abfd)->tdata.any))/* Create a ppcboot object.  Invoked via bfd_set_format.  */static booleanppcboot_mkobject (abfd)     bfd *abfd;{  if (!ppcboot_get_tdata (abfd))    ppcboot_set_tdata (abfd, bfd_zalloc (abfd, sizeof (ppcboot_data_t)));  return true;}/* Set the architecture to PowerPC */static booleanppcboot_set_arch_mach (abfd, arch, machine)     bfd *abfd;     enum bfd_architecture arch;     unsigned long machine;{  if (arch == bfd_arch_unknown)    arch = bfd_arch_powerpc;  else if (arch != bfd_arch_powerpc)    return false;  return bfd_default_set_arch_mach (abfd, arch, machine);}/* Any file may be considered to be a ppcboot file, provided the target   was not defaulted.  That is, it must be explicitly specified as   being ppcboot.  */static const bfd_target *ppcboot_object_p (abfd)     bfd *abfd;{  struct stat statbuf;  asection *sec;  ppcboot_hdr_t hdr;  size_t i;  ppcboot_data_t *tdata;  BFD_ASSERT (sizeof (ppcboot_hdr_t) == 1024);  if (abfd->target_defaulted)    {      bfd_set_error (bfd_error_wrong_format);      return NULL;    }  /* Find the file size.  */  if (bfd_stat (abfd, &statbuf) < 0)    {      bfd_set_error (bfd_error_system_call);      return NULL;    }  if ((size_t) statbuf.st_size < sizeof (ppcboot_hdr_t))    {      bfd_set_error (bfd_error_wrong_format);      return NULL;    }  if (bfd_read ((PTR) &hdr, sizeof (hdr), 1, abfd) != sizeof (hdr))    {      if (bfd_get_error () != bfd_error_system_call)	bfd_set_error (bfd_error_wrong_format);      return NULL;    }  /* Now do some basic checks.  */  for (i = 0; i < sizeof (hdr.pc_compatibility); i++)    if (hdr.pc_compatibility[i])      {	bfd_set_error (bfd_error_wrong_format);	return NULL;      }  if (hdr.signature[0] != SIGNATURE0 || hdr.signature[1] != SIGNATURE1)    {      bfd_set_error (bfd_error_wrong_format);      return NULL;    }  if (hdr.partition[0].partition_end.ind != PPC_IND)    {      bfd_set_error (bfd_error_wrong_format);      return NULL;    }  abfd->symcount = PPCBOOT_SYMS;  /* One data section.  */  sec = bfd_make_section (abfd, ".data");  if (sec == NULL)    return NULL;  sec->flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_CODE | SEC_HAS_CONTENTS;  sec->vma = 0;  sec->_raw_size = statbuf.st_size - sizeof (ppcboot_hdr_t);  sec->filepos = sizeof (ppcboot_hdr_t);  ppcboot_mkobject (abfd);  tdata = ppcboot_get_tdata (abfd);  tdata->sec = sec;  memcpy ((PTR) &tdata->header, (PTR) &hdr, sizeof (ppcboot_hdr_t));  ppcboot_set_arch_mach (abfd, bfd_arch_powerpc, 0);  return abfd->xvec;}#define ppcboot_close_and_cleanup _bfd_generic_close_and_cleanup#define ppcboot_bfd_free_cached_info _bfd_generic_bfd_free_cached_info#define ppcboot_new_section_hook _bfd_generic_new_section_hook/* Get contents of the only section.  */static booleanppcboot_get_section_contents (abfd, section, location, offset, count)     bfd *abfd;     asection *section ATTRIBUTE_UNUSED;     PTR location;     file_ptr offset;     bfd_size_type count;{  if (bfd_seek (abfd, offset + sizeof (ppcboot_hdr_t), SEEK_SET) != 0      || bfd_read (location, 1, count, abfd) != count)    return false;  return true;}/* Return the amount of memory needed to read the symbol table.  */static longppcboot_get_symtab_upper_bound (abfd)     bfd *abfd ATTRIBUTE_UNUSED;{  return (PPCBOOT_SYMS + 1) * sizeof (asymbol *);}/* Create a symbol name based on the bfd's filename.  */static char *mangle_name (abfd, suffix)     bfd *abfd;     char *suffix;{  int size;  char *buf;  char *p;  size = (strlen (bfd_get_filename (abfd))	  + strlen (suffix)	  + sizeof "_ppcboot__");  buf = (char *) bfd_alloc (abfd, size);  if (buf == NULL)    return "";

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?