X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fcoff-i386.c;h=c89b1fc13be634e369b0dd001e35866d8d362be2;hb=a8acd6eeb6dc2cc5460ece90f90ebe36b56b20ba;hp=e7c4e8a27942c6d5f957c88d0da7c346c2fd0c64;hpb=91d6fa6a035cc7d0b7be5c99c194a64cb80924b0;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c index e7c4e8a279..c89b1fc13b 100644 --- a/bfd/coff-i386.c +++ b/bfd/coff-i386.c @@ -1,7 +1,5 @@ /* BFD back-end for Intel 386 COFF files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 - 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. @@ -33,18 +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" -static bfd_reloc_status_type coff_i386_reloc - (bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **); +/* 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,15 +62,13 @@ static reloc_howto_type *coff_i386_reloc_type_lookup reloc type to make any required adjustments. */ static bfd_reloc_status_type -coff_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; +coff_i386_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) { symvalue diff; @@ -145,41 +138,46 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, #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; @@ -189,13 +187,11 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, /* Return TRUE if this relocation should appear in the output .reloc section. */ -static bfd_boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *)); - -static bfd_boolean in_reloc_p (abfd, howto) - bfd * abfd ATTRIBUTE_UNUSED; - reloc_howto_type *howto; +static bfd_boolean in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED, + reloc_howto_type *howto) { - return ! howto->pc_relative && howto->type != R_IMAGEBASE; + return ! howto->pc_relative && howto->type != R_IMAGEBASE + && howto->type != R_SECREL32; } #endif /* COFF_WITH_PE */ @@ -348,16 +344,18 @@ static reloc_howto_type howto_table[] = PCRELOFFSET) /* pcrel_offset */ }; +#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0])) + /* Turn a howto into a reloc nunmber */ #define SELECT_RELOC(x,howto) { x.r_type = howto->type; } #define BADMAG(x) I386BADMAG(x) #define I386 1 /* Customize coffcode.h */ -#define RTYPE2HOWTO(cache_ptr, dst) \ - ((cache_ptr)->howto = \ - ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0]) \ - ? howto_table + (dst)->r_type \ +#define RTYPE2HOWTO(cache_ptr, dst) \ + ((cache_ptr)->howto = \ + ((dst)->r_type < NUM_HOWTOS \ + ? howto_table + (dst)->r_type \ : NULL)) /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared @@ -383,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; \ @@ -394,7 +392,8 @@ static reloc_howto_type howto_table[] = cache_ptr->addend = - (ptr->section->vma + ptr->value); \ else \ cache_ptr->addend = 0; \ - if (ptr && howto_table[reloc.r_type].pc_relative) \ + if (ptr && reloc.r_type < NUM_HOWTOS \ + && howto_table[reloc.r_type].pc_relative) \ cache_ptr->addend += asect->vma; \ } @@ -412,24 +411,17 @@ static reloc_howto_type howto_table[] = and the regular routine is that we don't want to do anything for a relocatable link. */ -static bfd_boolean coff_pe_i386_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); - static bfd_boolean -coff_pe_i386_relocate_section (output_bfd, info, input_bfd, - input_section, contents, relocs, syms, - sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; +coff_pe_i386_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + struct internal_reloc *relocs, + 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, @@ -444,17 +436,16 @@ coff_pe_i386_relocate_section (output_bfd, info, input_bfd, /* Convert an rtype to howto for the COFF backend linker. */ static reloc_howto_type * -coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; +coff_i386_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + struct internal_reloc *rel, + struct coff_link_hash_entry *h, + struct internal_syment *sym, + bfd_vma *addendp) { reloc_howto_type *howto; - if (rel->r_type >= sizeof (howto_table) / sizeof (howto_table[0])) + if (rel->r_type >= NUM_HOWTOS) { bfd_set_error (bfd_error_bad_value); return NULL; @@ -506,11 +497,11 @@ coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp) *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; } @@ -522,13 +513,18 @@ coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp) *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; - if (h && (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak)) + if (h && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak)) osect_vma = h->root.u.def.section->output_section->vma; else { @@ -555,9 +551,8 @@ coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp) #define coff_bfd_reloc_name_lookup coff_i386_reloc_name_lookup static reloc_howto_type * -coff_i386_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +coff_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { switch (code) { @@ -591,7 +586,7 @@ coff_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, { unsigned int i; - for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++) + for (i = 0; i < NUM_HOWTOS; i++) if (howto_table[i].name != NULL && strcasecmp (howto_table[i].name, r_name) == 0) return &howto_table[i]; @@ -607,13 +602,8 @@ coff_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, a leading dot for local labels, so if TARGET_UNDERSCORE is defined we treat all symbols starting with L as local. */ -static bfd_boolean coff_i386_is_local_label_name - PARAMS ((bfd *, const char *)); - static bfd_boolean -coff_i386_is_local_label_name (abfd, name) - bfd *abfd; - const char *name; +coff_i386_is_local_label_name (bfd *abfd, const char *name) { if (name[0] == 'L') return TRUE; @@ -631,7 +621,7 @@ const bfd_target #ifdef TARGET_SYM TARGET_SYM = #else - i386coff_vec = + i386_coff_vec = #endif { #ifdef TARGET_NAME @@ -645,13 +635,13 @@ const bfd_target (HAS_RELOC | EXEC_P | /* object flags */ HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), + 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_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING #endif - | SEC_CODE | SEC_DATA), + | SEC_CODE | SEC_DATA | SEC_EXCLUDE ), #ifdef TARGET_UNDERSCORE TARGET_UNDERSCORE, /* leading underscore */ @@ -660,6 +650,7 @@ const bfd_target #endif '/', /* 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, @@ -668,25 +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_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, coff_object_p}, - {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), + + { /* 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 + 0, /* leading underscore */ +#endif + '/', /* 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, + + &bigobj_swap_table +}; +#endif \ No newline at end of file