nlm32-ppc.c

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

C
1,046
字号
/* Support for 32-bit PowerPC NLM (NetWare Loadable Module)   Copyright 1994, 1995, 2000 Free Software Foundation, Inc.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.  */#include "bfd.h"#include "sysdep.h"#include "libbfd.h"/* The format of a PowerPC NLM changed.  Define OLDFORMAT to get the   old format.  */#define ARCH_SIZE 32#include "nlm/ppc-ext.h"#define Nlm_External_Fixed_Header	Nlm32_powerpc_External_Fixed_Header#include "libnlm.h"#ifdef OLDFORMATstatic boolean nlm_powerpc_backend_object_p  PARAMS ((bfd *));static boolean nlm_powerpc_write_prefix  PARAMS ((bfd *));#endifstatic boolean nlm_powerpc_read_reloc  PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));static boolean nlm_powerpc_mangle_relocs  PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));static boolean nlm_powerpc_read_import  PARAMS ((bfd *, nlmNAME(symbol_type) *));#ifdef OLDFORMATstatic boolean nlm_powerpc_write_reloc  PARAMS ((bfd *, asection *, arelent *, int));#endifstatic boolean nlm_powerpc_write_import  PARAMS ((bfd *, asection *, arelent *));static boolean nlm_powerpc_write_external  PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));#ifndef OLDFORMATstatic boolean nlm_powerpc_set_public_section  PARAMS ((bfd *, nlmNAME(symbol_type) *));static bfd_vma nlm_powerpc_get_public_offset  PARAMS ((bfd *, asymbol *));#endif#ifdef OLDFORMAT/* The prefix header is only used in the old format.  *//* PowerPC NLM's have a prefix header before the standard NLM.  This   function reads it in, verifies the version, and seeks the bfd to   the location before the regular NLM header.  */static booleannlm_powerpc_backend_object_p (abfd)     bfd *abfd;{  struct nlm32_powerpc_external_prefix_header s;  if (bfd_read ((PTR) &s, sizeof s, 1, abfd) != sizeof s)    return false;  if (memcmp (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature) != 0      || bfd_h_get_32 (abfd, s.headerVersion) != NLM32_POWERPC_HEADER_VERSION)    return false;  return true;}/* Write out the prefix.  */static booleannlm_powerpc_write_prefix (abfd)     bfd *abfd;{  struct nlm32_powerpc_external_prefix_header s;  memset (&s, 0, sizeof s);  memcpy (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature);  bfd_h_put_32 (abfd, (bfd_vma) NLM32_POWERPC_HEADER_VERSION, s.headerVersion);  bfd_h_put_32 (abfd, (bfd_vma) 0, s.origins);  /* FIXME: What should we do about the date?  */  if (bfd_write ((PTR) &s, sizeof s, 1, abfd) != sizeof s)    return false;  return true;}#endif /* OLDFORMAT */#ifndef OLDFORMAT/* There is only one type of reloc in a PowerPC NLM.  */static reloc_howto_type nlm_powerpc_howto =  HOWTO (0,			/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 32,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 0,			/* special_function */	 "32",			/* name */	 true,			/* partial_inplace */	 0xffffffff,		/* src_mask */	 0xffffffff,		/* dst_mask */	 false);		/* pcrel_offset *//* Read a PowerPC NLM reloc.  */static booleannlm_powerpc_read_reloc (abfd, sym, secp, rel)     bfd *abfd;     nlmNAME(symbol_type) *sym;     asection **secp;     arelent *rel;{  bfd_byte temp[4];  bfd_vma val;  const char *name;  if (bfd_read (temp, sizeof (temp), 1, abfd) != sizeof (temp))    return false;  val = bfd_get_32 (abfd, temp);  /* The value is a word offset into either the code or data segment.     This is the location which needs to be adjusted.     The high bit is 0 if the value is an offset into the data     segment, or 1 if the value is an offset into the text segment.     If this is a relocation fixup rather than an imported symbol (the     sym argument is NULL), then the second most significant bit is 0     if the address of the data segment should be added to the     location addressed by the value, or 1 if the address of the text     segment should be added.     If this is an imported symbol, the second most significant bit is     not used and must be 0.  */  if ((val & NLM_HIBIT) == 0)    name = NLM_INITIALIZED_DATA_NAME;  else    {      name = NLM_CODE_NAME;      val &=~ NLM_HIBIT;    }  *secp = bfd_get_section_by_name (abfd, name);  if (sym == NULL)    {      if ((val & (NLM_HIBIT >> 1)) == 0)	name = NLM_INITIALIZED_DATA_NAME;      else	{	  name = NLM_CODE_NAME;	  val &=~ (NLM_HIBIT >> 1);	}      rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr;    }  rel->howto = &nlm_powerpc_howto;  rel->address = val << 2;  rel->addend = 0;  return true;}#else /* OLDFORMAT *//* This reloc handling is only applicable to the old format.  *//* How to process the various reloc types.  PowerPC NLMs use XCOFF   reloc types, and I have just copied the XCOFF reloc table here.  */static reloc_howto_type nlm_powerpc_howto_table[] ={  /* Standard 32 bit relocation.  */  HOWTO (0,	                /* type */	 0,	                /* rightshift */	 2,	                /* size (0 = byte, 1 = short, 2 = long) */	 32,	                /* bitsize */	 false,	                /* pc_relative */	 0,	                /* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 0,		        /* special_function */	 "R_POS",               /* name */	 true,	                /* partial_inplace */	 0xffffffff,            /* src_mask */	 0xffffffff,            /* dst_mask */	 false),                /* pcrel_offset */  /* 32 bit relocation, but store negative value.  */  HOWTO (1,	                /* type */	 0,	                /* rightshift */	 -2,	                /* size (0 = byte, 1 = short, 2 = long) */	 32,	                /* bitsize */	 false,	                /* pc_relative */	 0,	                /* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 0,		        /* special_function */	 "R_NEG",               /* name */	 true,	                /* partial_inplace */	 0xffffffff,            /* src_mask */	 0xffffffff,            /* dst_mask */	 false),                /* pcrel_offset */  /* 32 bit PC relative relocation.  */  HOWTO (2,	                /* type */	 0,	                /* rightshift */	 2,	                /* size (0 = byte, 1 = short, 2 = long) */	 32,	                /* bitsize */	 true,	                /* pc_relative */	 0,	                /* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 0,		        /* special_function */	 "R_REL",               /* name */	 true,	                /* partial_inplace */	 0xffffffff,            /* src_mask */	 0xffffffff,            /* dst_mask */	 false),                /* pcrel_offset */  /* 16 bit TOC relative relocation.  */  HOWTO (3,	                /* type */	 0,	                /* rightshift */	 1,	                /* size (0 = byte, 1 = short, 2 = long) */	 16,	                /* bitsize */	 false,	                /* pc_relative */	 0,	                /* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 0,		        /* special_function */	 "R_TOC",               /* name */	 true,	                /* partial_inplace */	 0xffff,	        /* src_mask */	 0xffff,        	/* dst_mask */	 false),                /* pcrel_offset */  /* I don't really know what this is.  */  HOWTO (4,	                /* type */	 1,	                /* rightshift */	 2,	                /* size (0 = byte, 1 = short, 2 = long) */	 32,	                /* bitsize */	 false,	                /* pc_relative */	 0,	                /* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 0,		        /* special_function */	 "R_RTB",               /* name */	 true,	                /* partial_inplace */	 0xffffffff,	        /* src_mask */	 0xffffffff,        	/* dst_mask */	 false),                /* pcrel_offset */  /* External TOC relative symbol.  */  HOWTO (5,	                /* type */	 0,	                /* rightshift */	 2,	                /* size (0 = byte, 1 = short, 2 = long) */	 16,	                /* bitsize */	 false,	                /* pc_relative */	 0,	                /* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 0,		        /* special_function */	 "R_GL",                /* name */	 true,	                /* partial_inplace */	 0xffff,	        /* src_mask */	 0xffff,        	/* dst_mask */	 false),                /* pcrel_offset */  /* Local TOC relative symbol.  */  HOWTO (6,	                /* type */	 0,	                /* rightshift */	 2,	                /* size (0 = byte, 1 = short, 2 = long) */	 16,	                /* bitsize */	 false,	                /* pc_relative */	 0,	                /* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 0,		        /* special_function */	 "R_TCL",               /* name */	 true,	                /* partial_inplace */	 0xffff,	        /* src_mask */	 0xffff,        	/* dst_mask */	 false),                /* pcrel_offset */  { 7 },  /* Non modifiable absolute branch.  */  HOWTO (8,	                /* type */	 0,	                /* rightshift */	 2,	                /* size (0 = byte, 1 = short, 2 = long) */	 26,	                /* bitsize */	 false,	                /* pc_relative */	 0,	                /* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 0,		        /* special_function */	 "R_BA",                /* name */	 true,	                /* partial_inplace */	 0x3fffffc,	        /* src_mask */	 0x3fffffc,        	/* dst_mask */	 false),                /* pcrel_offset */  { 9 },  /* Non modifiable relative branch.  */  HOWTO (0xa,	                /* type */	 0,	                /* rightshift */	 2,	                /* size (0 = byte, 1 = short, 2 = long) */	 26,	                /* bitsize */	 true,	                /* pc_relative */	 0,	                /* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 0,		        /* special_function */	 "R_BR",                /* name */	 true,	                /* partial_inplace */	 0x3fffffc,	        /* src_mask */	 0x3fffffc,        	/* dst_mask */	 false),                /* pcrel_offset */  { 0xb },  /* Indirect load.  */  HOWTO (0xc,	                /* type */	 0,	                /* rightshift */	 2,	                /* size (0 = byte, 1 = short, 2 = long) */	 16,	                /* bitsize */	 false,	                /* pc_relative */	 0,	                /* bitpos */

⌨️ 快捷键说明

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