nlmcode.h

来自「基于4个mips核的noc设计」· C头文件 代码 · 共 2,035 行 · 第 1/5 页

H
2,035
字号
/* NLM (NetWare Loadable Module) executable support for BFD.   Copyright 1993, 1994, 1995, 1998, 2000 Free Software Foundation, Inc.   Written by Fred Fish @ Cygnus Support, using ELF support as the   template.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"#include "libnlm.h"/* The functions in this file do not use the names they appear to use.   This file is actually compiled multiple times, once for each size   of NLM target we are using.  At each size we use a different name,   constructed by the macro nlmNAME.  For example, the function which   is named nlm_symbol_type below is actually named nlm32_symbol_type   in the final executable.  */#define Nlm_External_Fixed_Header	NlmNAME(External_Fixed_Header)#define Nlm_External_Version_Header	NlmNAME(External_Version_Header)#define Nlm_External_Copyright_Header	NlmNAME(External_Copyright_Header)#define Nlm_External_Extended_Header	NlmNAME(External_Extended_Header)#define Nlm_External_Custom_Header	NlmNAME(External_Custom_Header)#define Nlm_External_Cygnus_Ext_Header	NlmNAME(External_Cygnus_Ext_Header)#define nlm_symbol_type			nlmNAME(symbol_type)#define nlm_get_symtab_upper_bound	nlmNAME(get_symtab_upper_bound)#define nlm_get_symtab			nlmNAME(get_symtab)#define nlm_make_empty_symbol		nlmNAME(make_empty_symbol)#define nlm_print_symbol		nlmNAME(print_symbol)#define nlm_get_symbol_info		nlmNAME(get_symbol_info)#define nlm_get_reloc_upper_bound	nlmNAME(get_reloc_upper_bound)#define nlm_canonicalize_reloc		nlmNAME(canonicalize_reloc)#define nlm_object_p			nlmNAME(object_p)#define nlm_set_section_contents	nlmNAME(set_section_contents)#define nlm_write_object_contents	nlmNAME(write_object_contents)#define nlm_swap_fixed_header_in(abfd,src,dst) \  (nlm_swap_fixed_header_in_func(abfd)) (abfd,src,dst)#define nlm_swap_fixed_header_out(abfd,src,dst) \  (nlm_swap_fixed_header_out_func(abfd)) (abfd,src,dst)/* Forward declarations of static functions */static boolean add_bfd_section  PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword));static boolean nlm_swap_variable_header_in  PARAMS ((bfd *));static boolean nlm_swap_variable_header_out  PARAMS ((bfd *));static boolean find_nonzero  PARAMS ((PTR, size_t));static boolean nlm_swap_auxiliary_headers_in  PARAMS ((bfd *));static boolean nlm_swap_auxiliary_headers_out  PARAMS ((bfd *));static boolean nlm_slurp_symbol_table  PARAMS ((bfd *));static boolean nlm_slurp_reloc_fixups  PARAMS ((bfd *));static boolean nlm_compute_section_file_positions  PARAMS ((bfd *));static int nlm_external_reloc_compare  PARAMS ((const void *, const void *));/* Should perhaps use put_offset, put_word, etc.  For now, the two versions   can be handled by explicitly specifying 32 bits or "the long type".  */#if ARCH_SIZE == 64#define put_word	bfd_h_put_64#define get_word	bfd_h_get_64#endif#if ARCH_SIZE == 32#define put_word	bfd_h_put_32#define get_word	bfd_h_get_32#endifconst bfd_target *nlm_object_p (abfd)     bfd *abfd;{  struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd);  boolean (*backend_object_p) PARAMS ((bfd *));  PTR x_fxdhdr = NULL;  Nlm_Internal_Fixed_Header *i_fxdhdrp;  struct nlm_obj_tdata *new_tdata = NULL;  const char *signature;  enum bfd_architecture arch;  /* Some NLM formats have a prefix before the standard NLM fixed     header.  */  backend_object_p = nlm_backend_object_p_func (abfd);  if (backend_object_p)    {      if (!(*backend_object_p) (abfd))	goto got_wrong_format_error;    }  /* Read in the fixed length portion of the NLM header in external format.  */  x_fxdhdr = (PTR) bfd_malloc ((size_t) nlm_fixed_header_size (abfd));  if (x_fxdhdr == NULL)    goto got_no_match;  if (bfd_read ((PTR) x_fxdhdr, nlm_fixed_header_size (abfd), 1, abfd) !=      nlm_fixed_header_size (abfd))    {      if (bfd_get_error () != bfd_error_system_call)	goto got_wrong_format_error;      else	goto got_no_match;    }  /* Allocate an instance of the nlm_obj_tdata structure and hook it up to     the tdata pointer in the bfd.  */  new_tdata = ((struct nlm_obj_tdata *)	       bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata)));  if (new_tdata == NULL)    goto got_no_match;  nlm_tdata (abfd) = new_tdata;  i_fxdhdrp = nlm_fixed_header (abfd);  nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp);  free (x_fxdhdr);  x_fxdhdr = NULL;  /* Check to see if we have an NLM file for this backend by matching     the NLM signature.  */  signature = nlm_signature (abfd);  if (signature != NULL      && *signature != '\0'      && strncmp ((char *) i_fxdhdrp->signature, signature,		  NLM_SIGNATURE_SIZE) != 0)    goto got_wrong_format_error;  /* There's no supported way to discover the endianess of an NLM, so test for     a sane version number after doing byte swapping appropriate for this     XVEC.  (Hack alert!) */  if (i_fxdhdrp->version > 0xFFFF)    goto got_wrong_format_error;  /* There's no supported way to check for 32 bit versus 64 bit addresses,     so ignore this distinction for now.  (FIXME) */  /* Swap in the rest of the required header.  */  if (!nlm_swap_variable_header_in (abfd))    {      if (bfd_get_error () != bfd_error_system_call)	goto got_wrong_format_error;      else	goto got_no_match;    }  /* Add the sections supplied by all NLM's, and then read in the     auxiliary headers.  Reading the auxiliary headers may create     additional sections described in the cygnus_ext header.     From this point on we assume that we have an NLM, and do not     treat errors as indicating the wrong format.  */  if (!add_bfd_section (abfd, NLM_CODE_NAME,			i_fxdhdrp->codeImageOffset,			i_fxdhdrp->codeImageSize,			(SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS			 | SEC_RELOC))      || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,			   i_fxdhdrp->dataImageOffset,			   i_fxdhdrp->dataImageSize,			   (SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS			    | SEC_RELOC))      || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,			   (file_ptr) 0,			   i_fxdhdrp->uninitializedDataSize,			   SEC_ALLOC))    goto got_no_match;  if (!nlm_swap_auxiliary_headers_in (abfd))    goto got_no_match;  if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0      || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)    abfd->flags |= HAS_RELOC;  if (nlm_fixed_header (abfd)->numberOfPublics != 0      || nlm_fixed_header (abfd)->numberOfDebugRecords != 0      || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)    abfd->flags |= HAS_SYMS;  arch = nlm_architecture (abfd);  if (arch != bfd_arch_unknown)    bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);  abfd->flags |= EXEC_P;  bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset;  return (abfd->xvec);got_wrong_format_error:  bfd_set_error (bfd_error_wrong_format);got_no_match:  nlm_tdata (abfd) = preserved_tdata;  if (new_tdata != NULL)    bfd_release (abfd, new_tdata);  if (x_fxdhdr != NULL)    free (x_fxdhdr);  return (NULL);}/* Add a section to the bfd.  */static booleanadd_bfd_section (abfd, name, offset, size, flags)     bfd *abfd;     char *name;     file_ptr offset;     bfd_size_type size;     flagword flags;{  asection *newsect;  newsect = bfd_make_section (abfd, name);  if (newsect == NULL)    {      return (false);    }  newsect->vma = 0;		/* NLM's are relocatable.  */  newsect->_raw_size = size;  newsect->filepos = offset;  newsect->flags = flags;  newsect->alignment_power = bfd_log2 (0);	/* FIXME */  return (true);}/* Read and swap in the variable length header.  All the fields must   exist in the NLM, and must exist in the order they are read here.  */static booleannlm_swap_variable_header_in (abfd)     bfd *abfd;{  unsigned char temp[NLM_TARGET_LONG_SIZE];  /* Read the description length and text members.  */  if (bfd_read ((PTR) & nlm_variable_header (abfd)->descriptionLength,		sizeof (nlm_variable_header (abfd)->descriptionLength),		1, abfd) !=      sizeof (nlm_variable_header (abfd)->descriptionLength))    return (false);  if (bfd_read ((PTR) nlm_variable_header (abfd)->descriptionText,		nlm_variable_header (abfd)->descriptionLength + 1,		1, abfd) !=      (bfd_size_type) nlm_variable_header (abfd)->descriptionLength + 1)    return (false);  /* Read and convert the stackSize field.  */  if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))    return (false);  nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);  /* Read and convert the reserved field.  */  if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))    return (false);  nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);  /* Read the oldThreadName field.  This field is a fixed length string.  */  if (bfd_read ((PTR) nlm_variable_header (abfd)->oldThreadName,		sizeof (nlm_variable_header (abfd)->oldThreadName),		1, abfd) !=      sizeof (nlm_variable_header (abfd)->oldThreadName))    return (false);  /* Read the screen name length and text members.  */  if (bfd_read ((PTR) & nlm_variable_header (abfd)->screenNameLength,		sizeof (nlm_variable_header (abfd)->screenNameLength),		1, abfd) !=      sizeof (nlm_variable_header (abfd)->screenNameLength))    return (false);  if (bfd_read ((PTR) nlm_variable_header (abfd)->screenName,		nlm_variable_header (abfd)->screenNameLength + 1,		1, abfd) !=      (bfd_size_type) nlm_variable_header (abfd)->screenNameLength + 1)    return (false);  /* Read the thread name length and text members.  */  if (bfd_read ((PTR) & nlm_variable_header (abfd)->threadNameLength,		sizeof (nlm_variable_header (abfd)->threadNameLength),		1, abfd) !=      sizeof (nlm_variable_header (abfd)->threadNameLength))    return (false);  if (bfd_read ((PTR) nlm_variable_header (abfd)->threadName,		nlm_variable_header (abfd)->threadNameLength + 1,		1, abfd) !=      (bfd_size_type) nlm_variable_header (abfd)->threadNameLength + 1)    return (false);  return (true);}/* Swap and write out the variable length header.  All the fields must   exist in the NLM, and must exist in this order.  */static booleannlm_swap_variable_header_out (abfd)     bfd *abfd;{  unsigned char temp[NLM_TARGET_LONG_SIZE];  /* Write the description length and text members.  */  if (bfd_write ((PTR) & nlm_variable_header (abfd)->descriptionLength,		 sizeof (nlm_variable_header (abfd)->descriptionLength),		 1, abfd) !=      sizeof (nlm_variable_header (abfd)->descriptionLength))    return (false);  if (bfd_write ((PTR) nlm_variable_header (abfd)->descriptionText,		 nlm_variable_header (abfd)->descriptionLength + 1,		 1, abfd) !=      (bfd_size_type) nlm_variable_header (abfd)->descriptionLength + 1)    return (false);  /* Convert and write the stackSize field.  */  put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize,	    (bfd_byte *) temp);  if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))    return (false);  /* Convert and write the reserved field.  */  put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved,	    (bfd_byte *) temp);  if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))    return (false);  /* Write the oldThreadName field.  This field is a fixed length string.  */  if (bfd_write ((PTR) nlm_variable_header (abfd)->oldThreadName,		 sizeof (nlm_variable_header (abfd)->oldThreadName),		 1, abfd) !=      sizeof (nlm_variable_header (abfd)->oldThreadName))    return (false);  /* Write the screen name length and text members.  */  if (bfd_write ((PTR) & nlm_variable_header (abfd)->screenNameLength,		 sizeof (nlm_variable_header (abfd)->screenNameLength),		 1, abfd) !=      sizeof (nlm_variable_header (abfd)->screenNameLength))    return (false);  if (bfd_write ((PTR) nlm_variable_header (abfd)->screenName,		 nlm_variable_header (abfd)->screenNameLength + 1,		 1, abfd) !=      (bfd_size_type) nlm_variable_header (abfd)->screenNameLength + 1)    return (false);  /* Write the thread name length and text members.  */  if (bfd_write ((PTR) & nlm_variable_header (abfd)->threadNameLength,		 sizeof (nlm_variable_header (abfd)->threadNameLength),		 1, abfd) !=      sizeof (nlm_variable_header (abfd)->threadNameLength))    return (false);  if (bfd_write ((PTR) nlm_variable_header (abfd)->threadName,		 nlm_variable_header (abfd)->threadNameLength + 1,		 1, abfd) !=      (bfd_size_type) nlm_variable_header (abfd)->threadNameLength + 1)    return (false);  return (true);}/* Read and swap in the contents of all the auxiliary headers.  Because of   the braindead design, we have to do strcmps on strings of indeterminate   length to figure out what each auxiliary header is.  Even worse, we have   no way of knowing how many auxiliary headers there are or where the end   of the auxiliary headers are, except by finding something that doesn't   look like a known auxiliary header.  This means that the first new type   of auxiliary header added will break all existing tools that don't   recognize it.  */static booleannlm_swap_auxiliary_headers_in (abfd)     bfd *abfd;{  char tempstr[16];  long position;

⌨️ 快捷键说明

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