X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fcoff-i860.c;h=8573a8deb8f88e89b61f429875f0b75342261694;hb=d96c806b9210f2a9dc07f9ebfc811b3fc0c0f870;hp=1906615bee3446220e242a77c3d93882ee3f52b1;hpb=a62d170c661a4973cc04830c8fd349850e0d8977;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coff-i860.c b/bfd/coff-i860.c index 1906615bee..8573a8deb8 100644 --- a/bfd/coff-i860.c +++ b/bfd/coff-i860.c @@ -1,33 +1,37 @@ -/* BFD back-end for Intel 860 COFF files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2002, 2003 - Free Software Foundation, Inc. +/* BFD back-end for Intel i860 COFF files. + Copyright (C) 1990-2015 Free Software Foundation, Inc. Created mostly by substituting "860" for "386" in coff-i386.c Harry Dolan , October 1995 -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/i860.h" #include "coff/internal.h" +#ifndef bfd_pe_print_pdata +#define bfd_pe_print_pdata NULL +#endif + #include "libcoff.h" @@ -126,6 +130,23 @@ coff_i860_reloc (bfd *abfd, return bfd_reloc_continue; } +/* This is just a temporary measure until we teach bfd to generate + these relocations. */ + +static bfd_reloc_status_type +coff_i860_reloc_nyi (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED, + asection *input_section ATTRIBUTE_UNUSED, + bfd *output_bfd ATTRIBUTE_UNUSED, + char **error_message ATTRIBUTE_UNUSED) +{ + reloc_howto_type *howto = reloc_entry->howto; + (*_bfd_error_handler) (_("relocation `%s' not yet implemented"), howto->name); + return bfd_reloc_notsupported; +} + #ifndef PCRELOFFSET #define PCRELOFFSET FALSE #endif @@ -249,17 +270,184 @@ static reloc_howto_type howto_table[] = TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ - PCRELOFFSET) /* pcrel_offset */ + PCRELOFFSET), /* pcrel_offset */ + EMPTY_HOWTO (0x15), + EMPTY_HOWTO (0x16), + EMPTY_HOWTO (0x17), + EMPTY_HOWTO (0x18), + EMPTY_HOWTO (0x19), + EMPTY_HOWTO (0x1a), + EMPTY_HOWTO (0x1b), + HOWTO (COFF860_R_PAIR, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + coff_i860_reloc_nyi, /* special_function */ + "PAIR", /* name */ + FALSE, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + EMPTY_HOWTO (0x1d), + HOWTO (COFF860_R_HIGH, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + coff_i860_reloc, /* special_function */ + "HIGH", /* name */ + FALSE, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + HOWTO (COFF860_R_LOW0, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + coff_i860_reloc, /* special_function */ + "LOW0", /* name */ + FALSE, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + HOWTO (COFF860_R_LOW1, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + coff_i860_reloc, /* special_function */ + "LOW1", /* name */ + FALSE, /* partial_inplace */ + 0xfffe, /* src_mask */ + 0xfffe, /* dst_mask */ + FALSE), /* pcrel_offset */ + HOWTO (COFF860_R_LOW2, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + coff_i860_reloc, /* special_function */ + "LOW2", /* name */ + FALSE, /* partial_inplace */ + 0xfffc, /* src_mask */ + 0xfffc, /* dst_mask */ + FALSE), /* pcrel_offset */ + HOWTO (COFF860_R_LOW3, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + coff_i860_reloc, /* special_function */ + "LOW3", /* name */ + FALSE, /* partial_inplace */ + 0xfff8, /* src_mask */ + 0xfff8, /* dst_mask */ + FALSE), /* pcrel_offset */ + HOWTO (COFF860_R_LOW4, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + coff_i860_reloc, /* special_function */ + "LOW4", /* name */ + FALSE, /* partial_inplace */ + 0xfff0, /* src_mask */ + 0xfff0, /* dst_mask */ + FALSE), /* pcrel_offset */ + HOWTO (COFF860_R_SPLIT0, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + coff_i860_reloc_nyi, /* special_function */ + "SPLIT0", /* name */ + FALSE, /* partial_inplace */ + 0x1f07ff, /* src_mask */ + 0x1f07ff, /* dst_mask */ + FALSE), /* pcrel_offset */ + HOWTO (COFF860_R_SPLIT1, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + coff_i860_reloc_nyi, /* special_function */ + "SPLIT1", /* name */ + FALSE, /* partial_inplace */ + 0x1f07fe, /* src_mask */ + 0x1f07fe, /* dst_mask */ + FALSE), /* pcrel_offset */ + HOWTO (COFF860_R_SPLIT2, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + coff_i860_reloc_nyi, /* special_function */ + "SPLIT2", /* name */ + FALSE, /* partial_inplace */ + 0x1f07fc, /* src_mask */ + 0x1f07fc, /* dst_mask */ + FALSE), /* pcrel_offset */ + HOWTO (COFF860_R_HIGHADJ, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + coff_i860_reloc_nyi, /* special_function */ + "HIGHADJ", /* name */ + FALSE, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + HOWTO (COFF860_R_BRADDR, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_i860_reloc_nyi, /* special_function */ + "BRADDR", /* name */ + FALSE, /* partial_inplace */ + 0x3ffffff, /* src_mask */ + 0x3ffffff, /* dst_mask */ + TRUE) /* pcrel_offset */ }; -/* Turn a howto into a reloc nunmber */ +/* Turn a howto into a reloc number. */ #define SELECT_RELOC(x,howto) { x.r_type = howto->type; } #define BADMAG(x) I860BADMAG(x) #define I860 1 /* Customize coffcode.h */ -#define RTYPE2HOWTO(cache_ptr, dst) \ - (cache_ptr)->howto = howto_table + (dst)->r_type; +#define RTYPE2HOWTO(cache_ptr, dst) \ + ((cache_ptr)->howto = \ + ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0]) \ + ? howto_table + (dst)->r_type \ + : NULL)) /* For 860 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared library. On some other COFF targets STYP_BSS is normally @@ -279,25 +467,10 @@ static reloc_howto_type howto_table[] = FIXME: This macro refers to symbols and asect; these are from the calling function, not the macro arguments. */ -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - 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)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = - coffsym->native->u.syment.n_value; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if (ptr && howto_table[reloc.r_type].pc_relative) \ - cache_ptr->addend += asect->vma; \ - } +/* PR 17512: file: 0a38fb7c + Set an addend value, even if it is not going to be used. A tool + like coffdump might be used to print out the contents of the reloc. */ +#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) (cache_ptr)->addend = 0 /* We use the special COFF backend linker. */ #define coff_relocate_section _bfd_coff_generic_relocate_section @@ -313,6 +486,12 @@ coff_i860_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto; + if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0])) + { + bfd_set_error (bfd_error_bad_value); + return NULL; + } + howto = howto_table + rel->r_type; if (howto->pc_relative) @@ -329,7 +508,7 @@ coff_i860_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, BFD_ASSERT (h != NULL); /* I think we *do* want to bypass this. If we don't, I have seen some data - parameters get the wrong relcation address. If I link two versions + parameters get the wrong relocation address. If I link two versions with and without this section bypassed and then do a binary comparison, the addresses which are different can be looked up in the map. The case in which this section has been bypassed has addresses which correspond @@ -346,7 +525,127 @@ coff_i860_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, return howto; } -#define coff_rtype_to_howto coff_i860_rtype_to_howto +static reloc_howto_type * +coff_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) +{ + switch (code) + { + case BFD_RELOC_32: + return howto_table + R_DIR32; + case BFD_RELOC_860_PC26: + return howto_table + COFF860_R_BRADDR; + case BFD_RELOC_860_PC16: + /* ??? How to handle PC16 for COFF? SPLIT0 is close for now. */ + return howto_table + COFF860_R_SPLIT0; + case BFD_RELOC_860_LOW0: + return howto_table + COFF860_R_LOW0; + case BFD_RELOC_860_SPLIT0: + return howto_table + COFF860_R_SPLIT0; + case BFD_RELOC_860_LOW1: + return howto_table + COFF860_R_LOW1; + case BFD_RELOC_860_SPLIT1: + return howto_table + COFF860_R_SPLIT1; + case BFD_RELOC_860_LOW2: + return howto_table + COFF860_R_LOW2; + case BFD_RELOC_860_SPLIT2: + return howto_table + COFF860_R_SPLIT2; + case BFD_RELOC_860_LOW3: + return howto_table + COFF860_R_LOW3; + case BFD_RELOC_860_HIGHADJ: + return howto_table + COFF860_R_HIGHADJ; + case BFD_RELOC_860_HIGH: + return howto_table + COFF860_R_HIGH; + default: + BFD_FAIL (); + return 0; + } +} + +static reloc_howto_type * +coff_i860_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; +} + +/* This is called from coff_slurp_reloc_table for each relocation + entry. This special handling is due to the `PAIR' relocation + which has a different meaning for the `r_symndx' field. */ + +static void +i860_reloc_processing (arelent *cache_ptr, struct internal_reloc *dst, + asymbol **symbols, bfd *abfd, asection *asect) +{ + if (dst->r_type == COFF860_R_PAIR) + { + /* Handle the PAIR relocation specially. */ + cache_ptr->howto = howto_table + dst->r_type; + cache_ptr->address = dst->r_vaddr; + cache_ptr->addend = dst->r_symndx; + cache_ptr->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr; + } + else + { + /* For every other relocation, do exactly what coff_slurp_reloc_table + would do (which this code is taken directly from). */ + asymbol *ptr = NULL; + cache_ptr->address = dst->r_vaddr; + + if (dst->r_symndx != -1) + { + if (dst->r_symndx < 0 || dst->r_symndx >= obj_conv_table_size (abfd)) + { + (*_bfd_error_handler) + (_("%B: warning: illegal symbol index %ld in relocs"), + abfd, dst->r_symndx); + cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; + ptr = NULL; + } + else + { + cache_ptr->sym_ptr_ptr = (symbols + + obj_convert (abfd)[dst->r_symndx]); + ptr = *(cache_ptr->sym_ptr_ptr); + } + } + else + { + cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; + ptr = NULL; + } + + /* The symbols definitions that we have read in have been + relocated as if their sections started at 0. But the offsets + refering to the symbols in the raw data have not been + modified, so we have to have a negative addend to compensate. + + Note that symbols which used to be common must be left alone. */ + + /* Calculate any reloc addend by looking at the symbol. */ + CALC_ADDEND (abfd, ptr, (*dst), cache_ptr); + (void) ptr; + + cache_ptr->address -= asect->vma; + + /* Fill in the cache_ptr->howto field from dst->r_type. */ + RTYPE2HOWTO (cache_ptr, dst); + } +} + +#define coff_rtype_to_howto coff_i860_rtype_to_howto +#define coff_bfd_reloc_type_lookup coff_i860_reloc_type_lookup +#define coff_bfd_reloc_name_lookup coff_i860_reloc_name_lookup + +#define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \ + i860_reloc_processing (relent, reloc, symbols, abfd, section) #include "coffcode.h" @@ -360,7 +659,7 @@ const bfd_target #ifdef TARGET_SYM TARGET_SYM = #else - i860coff_vec = + i860_coff_vec = #endif { #ifdef TARGET_NAME @@ -380,6 +679,7 @@ const bfd_target '_', /* leading underscore */ '/', /* 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,