X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fcoff-i386.c;h=af92b40c3067d81c54bc647adf7553ea78e4eb7a;hb=493443a47f514251f12e08223b2c56f0fed69015;hp=65700b6038b201384be878eb30cf14459e095ba6;hpb=d1c6de6f1598529efe3f24af517aa94ae4de4d5d;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c index 65700b6038..af92b40c30 100644 --- a/bfd/coff-i386.c +++ b/bfd/coff-i386.c @@ -1,27 +1,28 @@ /* BFD back-end for Intel 386 COFF files. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004 + 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Written by Cygnus Support. -This file is part of BFD, the Binary File Descriptor library. + 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 -(at your option) any later version. + 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 3 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 of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + 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. */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "libbfd.h" #include "coff/i386.h" @@ -36,16 +37,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #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 +65,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; @@ -119,6 +120,8 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, here. */ if (howto->pc_relative && howto->pcrel_offset) diff = -(1 << howto->size); + else if (symbol->flags & BSF_WEAK) + diff = reloc_entry->addend - symbol->value; else diff = -reloc_entry->addend; } @@ -182,13 +185,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 */ @@ -405,22 +406,15 @@ 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) return TRUE; @@ -437,17 +431,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 >= sizeof (howto_table) / sizeof (howto_table[0])) { bfd_set_error (bfd_error_bad_value); return NULL; @@ -515,25 +508,26 @@ 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) + 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; @@ -544,11 +538,11 @@ coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp) } #define coff_bfd_reloc_type_lookup coff_i386_reloc_type_lookup +#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) { @@ -576,6 +570,20 @@ coff_i386_reloc_type_lookup (abfd, code) } } +static reloc_howto_type * +coff_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++) + if (howto_table[i].name != NULL + && strcasecmp (howto_table[i].name, r_name) == 0) + return &howto_table[i]; + + return NULL; +} + #define coff_rtype_to_howto coff_i386_rtype_to_howto #ifdef TARGET_UNDERSCORE @@ -584,13 +592,8 @@ coff_i386_reloc_type_lookup (abfd, code) 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; @@ -604,6 +607,9 @@ coff_i386_is_local_label_name (abfd, name) #include "coffcode.h" +#define _bfd_generic_find_nearest_line_discriminator \ + coff_find_nearest_line_discriminator + const bfd_target #ifdef TARGET_SYM TARGET_SYM = @@ -622,13 +628,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 */ @@ -637,6 +643,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, @@ -646,8 +653,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 */