X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fcoff-i386.c;h=803c28fcafcf04faa67a031b80eac5d282249902;hb=081b1afe5a8cfa02bf3b3cdefb80c266705c17d1;hp=81d3800123364005d064e50c75adc531bf78ca1c;hpb=3db64b009284dda3a1ce10a91beb1297475e60a7;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c index 81d3800123..803c28fcaf 100644 --- a/bfd/coff-i386.c +++ b/bfd/coff-i386.c @@ -1,14 +1,12 @@ /* BFD back-end for Intel 386 COFF files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2007 - Free Software Foundation, Inc. + Copyright (C) 1990-2016 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 modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -18,7 +16,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #include "sysdep.h" #include "bfd.h" @@ -36,16 +35,18 @@ #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 - 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 *)); + (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)); + (bfd *, bfd_reloc_code_real_type); #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) /* The page size is a guess based on ELF. */ @@ -62,15 +63,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 ATTRIBUTE_UNUSED, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) { symvalue diff; @@ -140,41 +139,41 @@ 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; + unsigned char *addr = (unsigned char *) data + reloc_entry->address; - 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; @@ -184,13 +183,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 */ @@ -343,16 +340,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 @@ -380,7 +379,7 @@ static reloc_howto_type howto_table[] = coffsym = (obj_symbols (abfd) \ + (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; \ @@ -389,7 +388,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; \ } @@ -407,24 +407,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, @@ -439,17 +432,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; @@ -517,25 +509,31 @@ coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp) *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase; } - if (rel->r_type == R_SECREL32) + /* 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 { - asection *sec; + asection *s; int i; /* Sigh, the only way to get the section to offset against is to find it the hard way. */ - for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++) - sec = sec->next; + for (s = abfd->sections, i = 1; i < sym->n_scnum; i++) + s = s->next; - osect_vma = sec->output_section->vma; + osect_vma = s->output_section->vma; } *addendp -= osect_vma; @@ -549,9 +547,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) { @@ -585,7 +582,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]; @@ -601,13 +598,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; @@ -625,7 +617,7 @@ const bfd_target #ifdef TARGET_SYM TARGET_SYM = #else - i386coff_vec = + i386_coff_vec = #endif { #ifdef TARGET_NAME @@ -639,13 +631,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 */ @@ -654,6 +646,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, @@ -663,8 +656,13 @@ const bfd_target 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_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, coff_object_p}, + /* bfd_check_format */ +#ifdef COFF_CHECK_FORMAT + {_bfd_dummy_target, COFF_CHECK_FORMAT, + bfd_generic_archive_p, COFF_CHECK_FORMAT}, +#else + {_bfd_dummy_target, coff_object_p, bfd_generic_archive_p, coff_object_p}, +#endif {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ bfd_false}, {bfd_false, coff_write_object_contents, /* bfd_write_contents */