coff-i386.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 624 行 · 第 1/2 页
C
624 行
/* BFD back-end for Intel 386 COFF files. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Written by Cygnus Support.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 "coff/i386.h"#include "coff/internal.h"#ifdef COFF_WITH_PE#include "coff/pe.h"#endif#ifdef COFF_GO32_EXE#include "coff/go32exe.h"#endif#include "libcoff.h"static bfd_reloc_status_type coff_i386_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static reloc_howto_type *coff_i386_rtype_to_howto PARAMS ((bfd *, asection *, struct internal_reloc *, struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *));static reloc_howto_type *coff_i386_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type));#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)/* The page size is a guess based on ELF. */#define COFF_PAGE_SIZE 0x1000/* For some reason when using i386 COFF the value stored in the .text section for a reference to a common symbol is the value itself plus any desired offset. Ian Taylor, Cygnus Support. *//* If we are producing relocateable output, we need to do some adjustments to the object file that are not done by the bfd_perform_relocation function. This function is called by every reloc type to make any required adjustments. */static bfd_reloc_status_typecoff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) bfd *abfd; arelent *reloc_entry; asymbol *symbol; PTR data; asection *input_section ATTRIBUTE_UNUSED; bfd *output_bfd; char **error_message ATTRIBUTE_UNUSED;{ symvalue diff;#ifndef COFF_WITH_PE if (output_bfd == (bfd *) NULL) return bfd_reloc_continue;#endif if (bfd_is_com_section (symbol->section)) {#ifndef COFF_WITH_PE /* We are relocating a common symbol. The current value in the object file is ORIG + OFFSET, where ORIG is the value of the common symbol as seen by the object file when it was compiled (this may be zero if the symbol was undefined) and OFFSET is the offset into the common symbol (normally zero, but may be non-zero when referring to a field in a common structure). ORIG is the negative of reloc_entry->addend, which is set by the CALC_ADDEND macro below. We want to replace the value in the object file with NEW + OFFSET, where NEW is the value of the common symbol which we are going to put in the final object file. NEW is symbol->value. */ diff = symbol->value + reloc_entry->addend;#else /* In PE mode, we do not offset the common symbol. */ diff = reloc_entry->addend;#endif } else { /* For some reason bfd_perform_relocation always effectively ignores the addend for a COFF target when producing relocateable output. This seems to be always wrong for 386 COFF, so we handle the addend here instead. */#ifdef COFF_WITH_PE if (output_bfd == (bfd *) NULL) { reloc_howto_type *howto = reloc_entry->howto; /* Although PC relative relocations are very similar between PE and non-PE formats, but they are off by 1 << howto->size bytes. For the external relocation, PE is very different from others. See md_apply_fix3 () in gas/config/tc-i386.c. When we link PE and non-PE object files together to generate a non-PE executable, we have to compensate it here. */ if (howto->pc_relative == true && howto->pcrel_offset == true) diff = -(1 << howto->size); else diff = -reloc_entry->addend; } else#endif diff = reloc_entry->addend; }#ifdef COFF_WITH_PE /* FIXME: How should this case be handled? */ if (reloc_entry->howto->type == R_IMAGEBASE && output_bfd != NULL && bfd_get_flavour(output_bfd) == bfd_target_coff_flavour) diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;#endif#define DOIT(x) \ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) if (diff != 0) { reloc_howto_type *howto = reloc_entry->howto; unsigned char *addr = (unsigned char *) data + reloc_entry->address; switch (howto->size) { case 0: { char x = bfd_get_8 (abfd, addr); DOIT (x); bfd_put_8 (abfd, x, addr); } break; case 1: { short x = bfd_get_16 (abfd, addr); DOIT (x); bfd_put_16 (abfd, x, addr); } break; case 2: { long x = bfd_get_32 (abfd, addr); DOIT (x); bfd_put_32 (abfd, x, addr); } break; default: abort (); } } /* Now let bfd_perform_relocation finish everything up. */ return bfd_reloc_continue;}#ifdef COFF_WITH_PE/* Return true if this relocation should appear in the output .reloc section. */static boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));static boolean in_reloc_p (abfd, howto) bfd * abfd ATTRIBUTE_UNUSED; reloc_howto_type *howto;{ return ! howto->pc_relative && howto->type != R_IMAGEBASE;}#endif /* COFF_WITH_PE */#ifndef PCRELOFFSET#define PCRELOFFSET false#endifstatic reloc_howto_type howto_table[] ={ EMPTY_HOWTO (0), EMPTY_HOWTO (1), EMPTY_HOWTO (2), EMPTY_HOWTO (3), EMPTY_HOWTO (4), EMPTY_HOWTO (5), HOWTO (R_DIR32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ coff_i386_reloc, /* special_function */ "dir32", /* name */ true, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ true), /* pcrel_offset */ /* PE IMAGE_REL_I386_DIR32NB relocation (7). */ HOWTO (R_IMAGEBASE, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ coff_i386_reloc, /* special_function */ "rva32", /* name */ true, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ false), /* pcrel_offset */ EMPTY_HOWTO (010), EMPTY_HOWTO (011), EMPTY_HOWTO (012), EMPTY_HOWTO (013), EMPTY_HOWTO (014), EMPTY_HOWTO (015), EMPTY_HOWTO (016), /* Byte relocation (017). */ HOWTO (R_RELBYTE, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 8, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ coff_i386_reloc, /* special_function */ "8", /* name */ true, /* partial_inplace */ 0x000000ff, /* src_mask */ 0x000000ff, /* dst_mask */ PCRELOFFSET), /* pcrel_offset */ /* 16-bit word relocation (020). */ HOWTO (R_RELWORD, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ coff_i386_reloc, /* special_function */ "16", /* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ PCRELOFFSET), /* pcrel_offset */ /* 32-bit longword relocation (021). */ HOWTO (R_RELLONG, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ coff_i386_reloc, /* special_function */ "32", /* name */ true, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ PCRELOFFSET), /* pcrel_offset */ /* Byte PC relative relocation (022). */ HOWTO (R_PCRBYTE, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 8, /* bitsize */ true, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ coff_i386_reloc, /* special_function */ "DISP8", /* name */ true, /* partial_inplace */ 0x000000ff, /* src_mask */ 0x000000ff, /* dst_mask */ PCRELOFFSET), /* pcrel_offset */ /* 16-bit word PC relative relocation (023). */ HOWTO (R_PCRWORD, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ true, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ coff_i386_reloc, /* special_function */ "DISP16", /* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ PCRELOFFSET), /* pcrel_offset */ /* 32-bit longword PC relative relocation (024). */ HOWTO (R_PCRLONG, /* type */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?