pexxigen.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,044 行 · 第 1/5 页
C
2,044 行
/* Support for the generic parts of PE/PEI; the common executable parts. 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.com>. PE/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.*//* This expands into COFF_WITH_pe or COFF_WITH_pep depending on whether we're compiling for straight PE or PE+. */#define COFF_WITH_XX#include "bfd.h"#include "sysdep.h"#include "libbfd.h"#include "coff/internal.h"/* NOTE: it's strange to be including an architecture specific header in what's supposed to be general (to PE/PEI) code. However, that's where the definitions are, and they don't vary per architecture within PE/PEI, so we get them from there. FIXME: The lack of variance is an assumption which may prove to be incorrect if new PE/PEI targets are created. */#ifdef COFF_WITH_pep# include "coff/ia64.h"#else# include "coff/i386.h"#endif#include "coff/pe.h"#include "libcoff.h"#include "libpei.h"#ifdef COFF_WITH_pep# undef AOUTSZ# define AOUTSZ PEPAOUTSZ# define PEAOUTHDR PEPAOUTHDR#endif/* FIXME: This file has various tests of POWERPC_LE_PE. Those tests worked when the code was in peicode.h, but no longer work now that the code is in peigen.c. PowerPC NT is said to be dead. If anybody wants to revive the code, you will have to figure out how to handle those issues. */static void add_data_entry PARAMS ((bfd *, struct internal_extra_pe_aouthdr *, int, char *, bfd_vma));static boolean pe_print_pdata PARAMS ((bfd *, PTR));static boolean pe_print_reloc PARAMS ((bfd *, PTR));/**********************************************************************/void_bfd_XXi_swap_sym_in (abfd, ext1, in1) bfd *abfd; PTR ext1; PTR in1;{ SYMENT *ext = (SYMENT *) ext1; struct internal_syment *in = (struct internal_syment *) in1; if (ext->e.e_name[0] == 0) { in->_n._n_n._n_zeroes = 0; in->_n._n_n._n_offset = bfd_h_get_32 (abfd, (bfd_byte *) ext->e.e.e_offset); } else { memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN); } in->n_value = bfd_h_get_32 (abfd, (bfd_byte *) ext->e_value); in->n_scnum = bfd_h_get_16 (abfd, (bfd_byte *) ext->e_scnum); if (sizeof (ext->e_type) == 2) { in->n_type = bfd_h_get_16 (abfd, (bfd_byte *) ext->e_type); } else { in->n_type = bfd_h_get_32 (abfd, (bfd_byte *) ext->e_type); } in->n_sclass = bfd_h_get_8 (abfd, ext->e_sclass); in->n_numaux = bfd_h_get_8 (abfd, ext->e_numaux);#ifndef STRICT_PE_FORMAT /* This is for Gnu-created DLLs. */ /* The section symbols for the .idata$ sections have class 0x68 (C_SECTION), which MS documentation indicates is a section symbol. Unfortunately, the value field in the symbol is simply a copy of the .idata section's flags rather than something useful. When these symbols are encountered, change the value to 0 so that they will be handled somewhat correctly in the bfd code. */ if (in->n_sclass == C_SECTION) { in->n_value = 0x0;#if 0 /* FIXME: This is clearly wrong. The problem seems to be that undefined C_SECTION symbols appear in the first object of a MS generated .lib file, and the symbols are not defined anywhere. */ in->n_scnum = 1; /* I have tried setting the class to 3 and using the following to set the section number. This will put the address of the pointer to the string kernel32.dll at addresses 0 and 0x10 off start of idata section which is not correct. */#if 0 if (strcmp (in->_n._n_name, ".idata$4") == 0) in->n_scnum = 3; else in->n_scnum = 2;#endif#else /* Create synthetic empty sections as needed. DJ */ if (in->n_scnum == 0) { asection *sec; for (sec = abfd->sections; sec; sec = sec->next) { if (strcmp (sec->name, in->n_name) == 0) { in->n_scnum = sec->target_index; break; } } } if (in->n_scnum == 0) { int unused_section_number = 0; asection *sec; char *name; for (sec = abfd->sections; sec; sec = sec->next) if (unused_section_number <= sec->target_index) unused_section_number = sec->target_index + 1; name = bfd_alloc (abfd, strlen (in->n_name) + 10); if (name == NULL) return; strcpy (name, in->n_name); sec = bfd_make_section_anyway (abfd, name); sec->vma = 0; sec->lma = 0; sec->_cooked_size = 0; sec->_raw_size = 0; sec->filepos = 0; sec->rel_filepos = 0; sec->reloc_count = 0; sec->line_filepos = 0; sec->lineno_count = 0; sec->userdata = NULL; sec->next = (asection *) NULL; sec->flags = 0; sec->alignment_power = 2; sec->flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD; sec->target_index = unused_section_number; in->n_scnum = unused_section_number; } in->n_sclass = C_STAT;#endif }#endif#ifdef coff_swap_sym_in_hook /* This won't work in peigen.c, but since it's for PPC PE, it's not worth fixing. */ coff_swap_sym_in_hook (abfd, ext1, in1);#endif}unsigned int_bfd_XXi_swap_sym_out (abfd, inp, extp) bfd *abfd; PTR inp; PTR extp;{ struct internal_syment *in = (struct internal_syment *) inp; SYMENT *ext = (SYMENT *) extp; if (in->_n._n_name[0] == 0) { bfd_h_put_32 (abfd, 0, (bfd_byte *) ext->e.e.e_zeroes); bfd_h_put_32 (abfd, in->_n._n_n._n_offset, (bfd_byte *) ext->e.e.e_offset); } else { memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN); } bfd_h_put_32 (abfd, in->n_value, (bfd_byte *) ext->e_value); bfd_h_put_16 (abfd, in->n_scnum, (bfd_byte *) ext->e_scnum); if (sizeof (ext->e_type) == 2) { bfd_h_put_16 (abfd, in->n_type, (bfd_byte *) ext->e_type); } else { bfd_h_put_32 (abfd, in->n_type, (bfd_byte *) ext->e_type); } bfd_h_put_8 (abfd, in->n_sclass, ext->e_sclass); bfd_h_put_8 (abfd, in->n_numaux, ext->e_numaux); return SYMESZ;}void_bfd_XXi_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1) bfd *abfd; PTR ext1; int type; int class; int indx ATTRIBUTE_UNUSED; int numaux ATTRIBUTE_UNUSED; PTR in1;{ AUXENT *ext = (AUXENT *) ext1; union internal_auxent *in = (union internal_auxent *) in1; switch (class) { case C_FILE: if (ext->x_file.x_fname[0] == 0) { in->x_file.x_n.x_zeroes = 0; in->x_file.x_n.x_offset = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_file.x_n.x_offset); } else { memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN); } return; case C_STAT: case C_LEAFSTAT: case C_HIDDEN: if (type == T_NULL) { in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext); in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext); in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext); in->x_scn.x_checksum = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_scn.x_checksum); in->x_scn.x_associated = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_scn.x_associated); in->x_scn.x_comdat = bfd_h_get_8 (abfd, (bfd_byte *) ext->x_scn.x_comdat); return; } break; } in->x_sym.x_tagndx.l = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_sym.x_tagndx); in->x_sym.x_tvndx = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_tvndx); if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class)) { in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext); in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext); } else { in->x_sym.x_fcnary.x_ary.x_dimen[0] = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]); in->x_sym.x_fcnary.x_ary.x_dimen[1] = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]); in->x_sym.x_fcnary.x_ary.x_dimen[2] = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]); in->x_sym.x_fcnary.x_ary.x_dimen[3] = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]); } if (ISFCN (type)) { in->x_sym.x_misc.x_fsize = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize); } else { in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO (abfd, ext); in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE (abfd, ext); }}unsigned int_bfd_XXi_swap_aux_out (abfd, inp, type, class, indx, numaux, extp) bfd *abfd; PTR inp; int type; int class; int indx ATTRIBUTE_UNUSED; int numaux ATTRIBUTE_UNUSED; PTR extp;{ union internal_auxent *in = (union internal_auxent *) inp; AUXENT *ext = (AUXENT *) extp; memset ((PTR) ext, 0, AUXESZ); switch (class) { case C_FILE: if (in->x_file.x_fname[0] == 0) { bfd_h_put_32 (abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes); bfd_h_put_32 (abfd, in->x_file.x_n.x_offset, (bfd_byte *) ext->x_file.x_n.x_offset); } else { memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN); } return AUXESZ; case C_STAT: case C_LEAFSTAT: case C_HIDDEN: if (type == T_NULL) { PUT_SCN_SCNLEN (abfd, in->x_scn.x_scnlen, ext); PUT_SCN_NRELOC (abfd, in->x_scn.x_nreloc, ext); PUT_SCN_NLINNO (abfd, in->x_scn.x_nlinno, ext); bfd_h_put_32 (abfd, in->x_scn.x_checksum, (bfd_byte *) ext->x_scn.x_checksum); bfd_h_put_16 (abfd, in->x_scn.x_associated, (bfd_byte *) ext->x_scn.x_associated); bfd_h_put_8 (abfd, in->x_scn.x_comdat, (bfd_byte *) ext->x_scn.x_comdat); return AUXESZ; } break; } bfd_h_put_32 (abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx); bfd_h_put_16 (abfd, in->x_sym.x_tvndx, (bfd_byte *) ext->x_sym.x_tvndx); if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class)) { PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext); PUT_FCN_ENDNDX (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext); } else { bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0], (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]); bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1], (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]); bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2], (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]); bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3], (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]); } if (ISFCN (type)) bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize, (bfd_byte *) ext->x_sym.x_misc.x_fsize); else
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?