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 + -
显示快捷键?