peicode.h
来自「基于4个mips核的noc设计」· C头文件 代码 · 共 1,324 行 · 第 1/3 页
H
1,324 行
/* Support for the generic parts of PE/PEI, for BFD. Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Written by Cygnus Solutions.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. *//*Most of this hacked by Steve Chamberlain, sac@cygnus.comPE/PEI rearrangement (and code added): Donn Terry Softway Systems, Inc.*//* Hey look, some documentation [and in a place you expect to find it]! The main reference for the pei format is "Microsoft Portable Executable and Common Object File Format Specification 4.1". Get it if you need to do some serious hacking on this code. Another reference: "Peering Inside the PE: A Tour of the Win32 Portable Executable File Format", MSJ 1994, Volume 9. The *sole* difference between the pe format and the pei format is that the latter has an MSDOS 2.0 .exe header on the front that prints the message "This app must be run under Windows." (or some such). (FIXME: Whether that statement is *really* true or not is unknown. Are there more subtle differences between pe and pei formats? For now assume there aren't. If you find one, then for God sakes document it here!) The Microsoft docs use the word "image" instead of "executable" because the former can also refer to a DLL (shared library). Confusion can arise because the `i' in `pei' also refers to "image". The `pe' format can also create images (i.e. executables), it's just that to run on a win32 system you need to use the pei format. FIXME: Please add more docs here so the next poor fool that has to hack on this code has a chance of getting something accomplished without wasting too much time.*/#include "libpei.h"static boolean (*pe_saved_coff_bfd_print_private_bfd_data) PARAMS ((bfd *, PTR)) =#ifndef coff_bfd_print_private_bfd_data NULL;#else coff_bfd_print_private_bfd_data;#undef coff_bfd_print_private_bfd_data#endifstatic boolean pe_print_private_bfd_data PARAMS ((bfd *, PTR));#define coff_bfd_print_private_bfd_data pe_print_private_bfd_datastatic boolean (*pe_saved_coff_bfd_copy_private_bfd_data) PARAMS ((bfd *, bfd *)) =#ifndef coff_bfd_copy_private_bfd_data NULL;#else coff_bfd_copy_private_bfd_data;#undef coff_bfd_copy_private_bfd_data#endifstatic boolean pe_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));#define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data#define coff_mkobject pe_mkobject#define coff_mkobject_hook pe_mkobject_hook#ifndef NO_COFF_RELOCSstatic void coff_swap_reloc_in PARAMS ((bfd *, PTR, PTR));static unsigned int coff_swap_reloc_out PARAMS ((bfd *, PTR, PTR));#endifstatic void coff_swap_filehdr_in PARAMS ((bfd *, PTR, PTR));static void coff_swap_scnhdr_in PARAMS ((bfd *, PTR, PTR));static boolean pe_mkobject PARAMS ((bfd *));static PTR pe_mkobject_hook PARAMS ((bfd *, PTR, PTR));#ifdef COFF_IMAGE_WITH_PE/* This structure contains static variables used by the ILF code. */typedef asection * asection_ptr;typedef struct{ bfd * abfd; bfd_byte * data; struct bfd_in_memory * bim; unsigned short magic; arelent * reltab; unsigned int relcount; coff_symbol_type * sym_cache; coff_symbol_type * sym_ptr; unsigned int sym_index; unsigned int * sym_table; unsigned int * table_ptr; combined_entry_type * native_syms; combined_entry_type * native_ptr; coff_symbol_type ** sym_ptr_table; coff_symbol_type ** sym_ptr_ptr; unsigned int sec_index; char * string_table; char * string_ptr; char * end_string_ptr; SYMENT * esym_table; SYMENT * esym_ptr; struct internal_reloc * int_reltab;}pe_ILF_vars;static asection_ptr pe_ILF_make_a_section PARAMS ((pe_ILF_vars *, const char *, unsigned int, flagword));static void pe_ILF_make_a_reloc PARAMS ((pe_ILF_vars *, bfd_vma, bfd_reloc_code_real_type, asection_ptr));static void pe_ILF_make_a_symbol PARAMS ((pe_ILF_vars *, const char *, const char *, asection_ptr, flagword));static void pe_ILF_save_relocs PARAMS ((pe_ILF_vars *, asection_ptr));static void pe_ILF_make_a_symbol_reloc PARAMS ((pe_ILF_vars *, bfd_vma, bfd_reloc_code_real_type, struct symbol_cache_entry **, unsigned int));static boolean pe_ILF_build_a_bfd PARAMS ((bfd *, unsigned short, bfd_byte *, bfd_byte *, unsigned int, unsigned int));static const bfd_target * pe_ILF_object_p PARAMS ((bfd *));static const bfd_target * pe_bfd_object_p PARAMS ((bfd *));#endif /* COFF_IMAGE_WITH_PE *//**********************************************************************/#ifndef NO_COFF_RELOCSstatic voidcoff_swap_reloc_in (abfd, src, dst) bfd *abfd; PTR src; PTR dst;{ RELOC *reloc_src = (RELOC *) src; struct internal_reloc *reloc_dst = (struct internal_reloc *) dst; reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr); reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx); reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type);#ifdef SWAP_IN_RELOC_OFFSET reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd, (bfd_byte *) reloc_src->r_offset);#endif}static unsigned intcoff_swap_reloc_out (abfd, src, dst) bfd *abfd; PTR src; PTR dst;{ struct internal_reloc *reloc_src = (struct internal_reloc *)src; struct external_reloc *reloc_dst = (struct external_reloc *)dst; bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr); bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx); bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *) reloc_dst->r_type);#ifdef SWAP_OUT_RELOC_OFFSET SWAP_OUT_RELOC_OFFSET(abfd, reloc_src->r_offset, (bfd_byte *) reloc_dst->r_offset);#endif#ifdef SWAP_OUT_RELOC_EXTRA SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst);#endif return RELSZ;}#endif /* not NO_COFF_RELOCS */static voidcoff_swap_filehdr_in (abfd, src, dst) bfd *abfd; PTR src; PTR dst;{ FILHDR *filehdr_src = (FILHDR *) src; struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst; filehdr_dst->f_magic = bfd_h_get_16(abfd, (bfd_byte *) filehdr_src->f_magic); filehdr_dst->f_nscns = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_nscns); filehdr_dst->f_timdat = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_timdat); filehdr_dst->f_nsyms = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_nsyms); filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags); filehdr_dst->f_symptr = bfd_h_get_32 (abfd, (bfd_byte *) filehdr_src->f_symptr); /* Other people's tools sometimes generate headers with an nsyms but a zero symptr. */ if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0) { filehdr_dst->f_nsyms = 0; filehdr_dst->f_flags |= F_LSYMS; } filehdr_dst->f_opthdr = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_opthdr);}#ifdef COFF_IMAGE_WITH_PE# define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out#else# define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out#endifstatic voidcoff_swap_scnhdr_in (abfd, ext, in) bfd *abfd; PTR ext; PTR in;{ SCNHDR *scnhdr_ext = (SCNHDR *) ext; struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in; memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name)); scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr); scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr); scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size); scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr); scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr); scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr); scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags); /* MS handles overflow of line numbers by carrying into the reloc field (it appears). Since it's supposed to be zero for PE *IMAGE* format, that's safe. This is still a bit iffy. */#ifdef COFF_IMAGE_WITH_PE scnhdr_int->s_nlnno = (bfd_h_get_16 (abfd, (bfd_byte *) scnhdr_ext->s_nlnno) + (bfd_h_get_16 (abfd, (bfd_byte *) scnhdr_ext->s_nreloc) << 16)); scnhdr_int->s_nreloc = 0;#else scnhdr_int->s_nreloc = bfd_h_get_16 (abfd, (bfd_byte *) scnhdr_ext->s_nreloc); scnhdr_int->s_nlnno = bfd_h_get_16 (abfd, (bfd_byte *) scnhdr_ext->s_nlnno);#endif if (scnhdr_int->s_vaddr != 0) { scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase; scnhdr_int->s_vaddr &= 0xffffffff; }#ifndef COFF_NO_HACK_SCNHDR_SIZE /* If this section holds uninitialized data, use the virtual size (stored in s_paddr) instead of the physical size. */ if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0) { scnhdr_int->s_size = scnhdr_int->s_paddr; /* This code used to set scnhdr_int->s_paddr to 0. However, coff_set_alignment_hook stores s_paddr in virt_size, which only works if it correctly holds the virtual size of the section. */ }#endif}static booleanpe_mkobject (abfd) bfd * abfd;{ pe_data_type *pe; abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type)); if (abfd->tdata.pe_obj_data == 0) return false; pe = pe_data (abfd); pe->coff.pe = 1; /* in_reloc_p is architecture dependent. */ pe->in_reloc_p = in_reloc_p;#ifdef PEI_FORCE_MINIMUM_ALIGNMENT pe->force_minimum_alignment = 1;#endif#ifdef PEI_TARGET_SUBSYSTEM pe->target_subsystem = PEI_TARGET_SUBSYSTEM;#endif return true;}/* Create the COFF backend specific information. */static PTRpe_mkobject_hook (abfd, filehdr, aouthdr) bfd * abfd; PTR filehdr; PTR aouthdr ATTRIBUTE_UNUSED;{ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; pe_data_type *pe; if (pe_mkobject (abfd) == false) return NULL; pe = pe_data (abfd); pe->coff.sym_filepos = internal_f->f_symptr; /* These members communicate important constants about the symbol table to GDB's symbol-reading code. These `constants' unfortunately vary among coff implementations... */ pe->coff.local_n_btmask = N_BTMASK; pe->coff.local_n_btshft = N_BTSHFT; pe->coff.local_n_tmask = N_TMASK; pe->coff.local_n_tshift = N_TSHIFT; pe->coff.local_symesz = SYMESZ; pe->coff.local_auxesz = AUXESZ; pe->coff.local_linesz = LINESZ; pe->coff.timestamp = internal_f->f_timdat; obj_raw_syment_count (abfd) = obj_conv_table_size (abfd) = internal_f->f_nsyms; pe->real_flags = internal_f->f_flags; if ((internal_f->f_flags & F_DLL) != 0) pe->dll = 1; if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0) abfd->flags |= HAS_DEBUG;#ifdef COFF_IMAGE_WITH_PE if (aouthdr) pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;#endif#ifdef ARM if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags)) coff_data (abfd) ->flags = 0;#endif return (PTR) pe;}static booleanpe_print_private_bfd_data (abfd, vfile) bfd *abfd; PTR vfile;{ FILE *file = (FILE *) vfile; if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile)) return false; if (pe_saved_coff_bfd_print_private_bfd_data != NULL) { fputc ('\n', file); return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile); } return true;}/* Copy any private info we understand from the input bfd to the output bfd. */static booleanpe_bfd_copy_private_bfd_data (ibfd, obfd) bfd *ibfd, *obfd;{ if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd)) return false; if (pe_saved_coff_bfd_copy_private_bfd_data) return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd); return true;}#define coff_bfd_copy_private_section_data \ _bfd_XX_bfd_copy_private_section_data#define coff_get_symbol_info _bfd_XX_get_symbol_info#ifdef COFF_IMAGE_WITH_PE/* Code to handle Microsoft's Image Library Format. Also known as LINK6 format. Documentation about this format can be found at: http://msdn.microsoft.com/library/specs/pecoff_section8.htm *//* The following constants specify the sizes of the various data structures that we have to create in order to build a bfd describing an ILF object file. The final "+ 1" in the definitions of SIZEOF_IDATA6 and SIZEOF_IDATA7 below is to allow for the possibility that we might need a padding byte in order to ensure 16 bit alignment for the section's contents. The value for SIZEOF_ILF_STRINGS is computed as follows: There will be NUM_ILF_SECTIONS section symbols. Allow 9 characters per symbol for their names (longest section name is .idata$x). There will be two symbols for the imported value, one the symbol name and one with _imp__ prefixed. Allowing for the terminating nul's this is strlen (symbol_name) * 2 + 8 + 21 + strlen (source_dll). The strings in the string table must start STRING__SIZE_SIZE bytes into the table in order to for the string lookup code in coffgen/coffcode to work. */#define NUM_ILF_RELOCS 8#define NUM_ILF_SECTIONS 6#define NUM_ILF_SYMS (2 + NUM_ILF_SECTIONS)#define SIZEOF_ILF_SYMS (NUM_ILF_SYMS * sizeof (* vars.sym_cache))
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?