X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fcoff-i386.c;h=c89b1fc13be634e369b0dd001e35866d8d362be2;hb=41792d688a5a1f158d6e9ecda2b603ae122d69a1;hp=848d69b91c0491fc7ae5c445d8444af21877357f;hpb=36e9d67b868c85232ab630514260f0d9c9c6b27b;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c index 848d69b91c..c89b1fc13b 100644 --- a/bfd/coff-i386.c +++ b/bfd/coff-i386.c @@ -1,5 +1,5 @@ /* BFD back-end for Intel 386 COFF files. - Copyright (C) 1990-2014 Free Software Foundation, Inc. + Copyright (C) 1990-2020 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -31,16 +31,15 @@ #include "coff/pe.h" #endif -#ifdef COFF_GO32_EXE -#include "coff/go32exe.h" -#endif - #ifndef bfd_pe_print_pdata #define bfd_pe_print_pdata NULL #endif #include "libcoff.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + static reloc_howto_type *coff_i386_rtype_to_howto (bfd *, asection *, struct internal_reloc *, struct coff_link_hash_entry *, struct internal_syment *, @@ -67,7 +66,7 @@ coff_i386_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, void * data, - asection *input_section ATTRIBUTE_UNUSED, + asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) { @@ -139,41 +138,46 @@ coff_i386_reloc (bfd *abfd, #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; + if (diff != 0) + { + reloc_howto_type *howto = reloc_entry->howto; + bfd_size_type octets = (reloc_entry->address + * OCTETS_PER_BYTE (abfd, input_section)); + unsigned char *addr = (unsigned char *) data + octets; + + if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets)) + return bfd_reloc_outofrange; - switch (howto->size) + switch (howto->size) + { + case 0: { - 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, (bfd_vma) x, addr); - } - break; - - case 2: - { - long x = bfd_get_32 (abfd, addr); - DOIT (x); - bfd_put_32 (abfd, (bfd_vma) x, addr); - } - break; - - default: - abort (); + 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, (bfd_vma) x, addr); + } + break; + + case 2: + { + long x = bfd_get_32 (abfd, addr); + DOIT (x); + bfd_put_32 (abfd, (bfd_vma) x, addr); + } + break; + + default: + abort (); + } + } /* Now let bfd_perform_relocation finish everything up. */ return bfd_reloc_continue; @@ -377,9 +381,9 @@ static reloc_howto_type howto_table[] = coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ + + (cache_ptr->sym_ptr_ptr - symbols)); \ else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ + coffsym = coff_symbol_from (ptr); \ if (coffsym != (coff_symbol_type *) NULL \ && coffsym->native->u.syment.n_scnum == 0) \ cache_ptr->addend = - coffsym->native->u.syment.n_value; \ @@ -417,7 +421,7 @@ coff_pe_i386_relocate_section (bfd *output_bfd, struct internal_syment *syms, asection **sections) { - if (info->relocatable) + if (bfd_link_relocatable (info)) return TRUE; return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, @@ -493,11 +497,11 @@ coff_i386_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, *addendp -= 4; /* If the symbol is defined, then the generic code is going to - add back the symbol value in order to cancel out an - adjustment it made to the addend. However, we set the addend - to 0 at the start of this function. We need to adjust here, - to avoid the adjustment the generic code will make. FIXME: - This is getting a bit hackish. */ + add back the symbol value in order to cancel out an + adjustment it made to the addend. However, we set the addend + to 0 at the start of this function. We need to adjust here, + to avoid the adjustment the generic code will make. FIXME: + This is getting a bit hackish. */ if (sym != NULL && sym->n_scnum != 0) *addendp -= sym->n_value; } @@ -509,7 +513,12 @@ coff_i386_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase; } - BFD_ASSERT (sym != NULL); + /* PR 17099 - Absolute R_PCRLONG relocations do not need a symbol. */ + if (rel->r_type == R_PCRLONG && sym == NULL) + *addendp -= rel->r_vaddr; + else + BFD_ASSERT (sym != NULL); + if (rel->r_type == R_SECREL32 && sym != NULL) { bfd_vma osect_vma; @@ -650,30 +659,117 @@ const bfd_target bfd_getl32, bfd_getl_signed_32, bfd_putl32, bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ +#ifndef COFF_CHECK_FORMAT +#define COFF_CHECK_FORMAT coff_object_p +#endif +#ifndef COFF_WRITE_CONTENTS +#define COFF_WRITE_CONTENTS coff_write_object_contents +#endif + /* Note that we allow an object file to be treated as a core file as well. */ - /* bfd_check_format */ -#ifdef COFF_CHECK_FORMAT - {_bfd_dummy_target, COFF_CHECK_FORMAT, - bfd_generic_archive_p, COFF_CHECK_FORMAT}, + + { /* bfd_check_format */ + _bfd_dummy_target, + COFF_CHECK_FORMAT, + bfd_generic_archive_p, + COFF_CHECK_FORMAT + }, + { /* bfd_set_format */ + _bfd_bool_bfd_false_error, + coff_mkobject, + _bfd_generic_mkarchive, + _bfd_bool_bfd_false_error + }, + { /* bfd_write_contents */ + _bfd_bool_bfd_false_error, + COFF_WRITE_CONTENTS, + _bfd_write_archive_contents, + _bfd_bool_bfd_false_error + }, + + BFD_JUMP_TABLE_GENERIC (coff), + BFD_JUMP_TABLE_COPY (coff), + BFD_JUMP_TABLE_CORE (_bfd_nocore), + BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), + BFD_JUMP_TABLE_SYMBOLS (coff), + BFD_JUMP_TABLE_RELOCS (coff), + BFD_JUMP_TABLE_WRITE (coff), + BFD_JUMP_TABLE_LINK (coff), + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + + NULL, + + COFF_SWAP_TABLE +}; + +#ifdef COFF_WITH_PE_BIGOBJ +const bfd_target + TARGET_SYM_BIG = +{ + TARGET_NAME_BIG, + bfd_target_coff_flavour, + BFD_ENDIAN_LITTLE, /* data byte order is little */ + BFD_ENDIAN_LITTLE, /* header byte order is little */ + + (HAS_RELOC | EXEC_P | /* object flags */ + HAS_LINENO | HAS_DEBUG | + HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS ), + + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */ +#ifdef COFF_WITH_PE + | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING +#endif + | SEC_CODE | SEC_DATA | SEC_EXCLUDE ), + +#ifdef TARGET_UNDERSCORE + TARGET_UNDERSCORE, /* leading underscore */ #else - {_bfd_dummy_target, coff_object_p, bfd_generic_archive_p, coff_object_p}, + 0, /* leading underscore */ #endif - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + '/', /* ar_pad_char */ + 15, /* ar_max_namelen */ + 0, /* match priority. */ + + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ + +/* Note that we allow an object file to be treated as a core file as well. */ + + { /* bfd_check_format */ + _bfd_dummy_target, + COFF_CHECK_FORMAT, + bfd_generic_archive_p, + COFF_CHECK_FORMAT + }, + { /* bfd_set_format */ + _bfd_bool_bfd_false_error, + coff_mkobject, + _bfd_generic_mkarchive, + _bfd_bool_bfd_false_error + }, + { /* bfd_write_contents */ + _bfd_bool_bfd_false_error, + COFF_WRITE_CONTENTS, + _bfd_write_archive_contents, + _bfd_bool_bfd_false_error + }, + + BFD_JUMP_TABLE_GENERIC (coff), + BFD_JUMP_TABLE_COPY (coff), + BFD_JUMP_TABLE_CORE (_bfd_nocore), + BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), + BFD_JUMP_TABLE_SYMBOLS (coff), + BFD_JUMP_TABLE_RELOCS (coff), + BFD_JUMP_TABLE_WRITE (coff), + BFD_JUMP_TABLE_LINK (coff), + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), NULL, - COFF_SWAP_TABLE + &bigobj_swap_table }; +#endif \ No newline at end of file